bba.c revision 1.12.2.2 1 1.12.2.2 bouyer /* $NetBSD: bba.c,v 1.12.2.2 2000/11/20 11:43:13 bouyer Exp $ */
2 1.12.2.2 bouyer
3 1.12.2.2 bouyer /*
4 1.12.2.2 bouyer * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 1.12.2.2 bouyer * All rights reserved.
6 1.12.2.2 bouyer *
7 1.12.2.2 bouyer * Redistribution and use in source and binary forms, with or without
8 1.12.2.2 bouyer * modification, are permitted provided that the following conditions
9 1.12.2.2 bouyer * are met:
10 1.12.2.2 bouyer * 1. Redistributions of source code must retain the above copyright
11 1.12.2.2 bouyer * notice, this list of conditions and the following disclaimer.
12 1.12.2.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
13 1.12.2.2 bouyer * notice, this list of conditions and the following disclaimer in the
14 1.12.2.2 bouyer * documentation and/or other materials provided with the distribution.
15 1.12.2.2 bouyer * 3. All advertising materials mentioning features or use of this software
16 1.12.2.2 bouyer * must display the following acknowledgement:
17 1.12.2.2 bouyer * This product includes software developed by the NetBSD
18 1.12.2.2 bouyer * Foundation, Inc. and its contributors.
19 1.12.2.2 bouyer * 4. Neither the name of The NetBSD Foundation nor the names of its
20 1.12.2.2 bouyer * contributors may be used to endorse or promote products derived
21 1.12.2.2 bouyer * from this software without specific prior written permission.
22 1.12.2.2 bouyer *
23 1.12.2.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 1.12.2.2 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 1.12.2.2 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 1.12.2.2 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 1.12.2.2 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 1.12.2.2 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 1.12.2.2 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 1.12.2.2 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 1.12.2.2 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 1.12.2.2 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 1.12.2.2 bouyer * POSSIBILITY OF SUCH DAMAGE.
34 1.12.2.2 bouyer */
35 1.12.2.2 bouyer
36 1.12.2.2 bouyer /* maxine/alpha baseboard audio (bba) */
37 1.12.2.2 bouyer
38 1.12.2.2 bouyer #include <sys/param.h>
39 1.12.2.2 bouyer #include <sys/systm.h>
40 1.12.2.2 bouyer #include <sys/kernel.h>
41 1.12.2.2 bouyer #include <sys/device.h>
42 1.12.2.2 bouyer #include <sys/malloc.h>
43 1.12.2.2 bouyer
44 1.12.2.2 bouyer #include <machine/bus.h>
45 1.12.2.2 bouyer #include <machine/autoconf.h>
46 1.12.2.2 bouyer #include <machine/cpu.h>
47 1.12.2.2 bouyer
48 1.12.2.2 bouyer #include <sys/audioio.h>
49 1.12.2.2 bouyer #include <dev/audio_if.h>
50 1.12.2.2 bouyer
51 1.12.2.2 bouyer #include <dev/ic/am7930reg.h>
52 1.12.2.2 bouyer #include <dev/ic/am7930var.h>
53 1.12.2.2 bouyer
54 1.12.2.2 bouyer #include <dev/tc/tcvar.h>
55 1.12.2.2 bouyer #include <dev/tc/ioasicreg.h>
56 1.12.2.2 bouyer #include <dev/tc/ioasicvar.h>
57 1.12.2.2 bouyer
58 1.12.2.2 bouyer #ifdef AUDIO_DEBUG
59 1.12.2.2 bouyer #define DPRINTF(x) if (am7930debug) printf x
60 1.12.2.2 bouyer #else
61 1.12.2.2 bouyer #define DPRINTF(x)
62 1.12.2.2 bouyer #endif /* AUDIO_DEBUG */
63 1.12.2.2 bouyer
64 1.12.2.2 bouyer #define BBA_MAX_DMA_SEGMENTS 16
65 1.12.2.2 bouyer #define BBA_DMABUF_SIZE (BBA_MAX_DMA_SEGMENTS*IOASIC_DMA_BLOCKSIZE)
66 1.12.2.2 bouyer #define BBA_DMABUF_ALIGN IOASIC_DMA_BLOCKSIZE
67 1.12.2.2 bouyer #define BBA_DMABUF_BOUNDARY 0
68 1.12.2.2 bouyer
69 1.12.2.2 bouyer struct bba_mem {
70 1.12.2.2 bouyer struct bba_mem *next;
71 1.12.2.2 bouyer bus_addr_t addr;
72 1.12.2.2 bouyer bus_size_t size;
73 1.12.2.2 bouyer caddr_t kva;
74 1.12.2.2 bouyer };
75 1.12.2.2 bouyer
76 1.12.2.2 bouyer struct bba_dma_state {
77 1.12.2.2 bouyer bus_dmamap_t dmam; /* dma map */
78 1.12.2.2 bouyer int active;
79 1.12.2.2 bouyer int curseg; /* current segment in dma buffer */
80 1.12.2.2 bouyer void (*intr)__P((void *)); /* higher-level audio handler */
81 1.12.2.2 bouyer void *intr_arg;
82 1.12.2.2 bouyer };
83 1.12.2.2 bouyer
84 1.12.2.2 bouyer struct bba_softc {
85 1.12.2.2 bouyer struct am7930_softc sc_am7930; /* glue to MI code */
86 1.12.2.2 bouyer
87 1.12.2.2 bouyer bus_space_tag_t sc_bst; /* IOASIC bus tag/handle */
88 1.12.2.2 bouyer bus_space_handle_t sc_bsh;
89 1.12.2.2 bouyer bus_dma_tag_t sc_dmat;
90 1.12.2.2 bouyer bus_space_handle_t sc_codec_bsh; /* codec bus space handle */
91 1.12.2.2 bouyer
92 1.12.2.2 bouyer struct bba_mem *sc_mem_head; /* list of buffers */
93 1.12.2.2 bouyer
94 1.12.2.2 bouyer struct bba_dma_state sc_tx_dma_state;
95 1.12.2.2 bouyer struct bba_dma_state sc_rx_dma_state;
96 1.12.2.2 bouyer };
97 1.12.2.2 bouyer
98 1.12.2.2 bouyer int bba_match __P((struct device *, struct cfdata *, void *));
99 1.12.2.2 bouyer void bba_attach __P((struct device *, struct device *, void *));
100 1.12.2.2 bouyer
101 1.12.2.2 bouyer struct cfattach bba_ca = {
102 1.12.2.2 bouyer sizeof(struct bba_softc), bba_match, bba_attach
103 1.12.2.2 bouyer };
104 1.12.2.2 bouyer
105 1.12.2.2 bouyer /*
106 1.12.2.2 bouyer * Define our interface into the am7930 MI driver.
107 1.12.2.2 bouyer */
108 1.12.2.2 bouyer
109 1.12.2.2 bouyer u_int8_t bba_codec_iread __P((struct am7930_softc *, int));
110 1.12.2.2 bouyer u_int16_t bba_codec_iread16 __P((struct am7930_softc *, int));
111 1.12.2.2 bouyer void bba_codec_iwrite __P((struct am7930_softc *, int, u_int8_t));
112 1.12.2.2 bouyer void bba_codec_iwrite16 __P((struct am7930_softc *, int, u_int16_t));
113 1.12.2.2 bouyer void bba_onopen __P((struct am7930_softc *sc));
114 1.12.2.2 bouyer void bba_onclose __P((struct am7930_softc *sc));
115 1.12.2.2 bouyer void bba_output_conv __P((void *, u_int8_t *, int));
116 1.12.2.2 bouyer void bba_input_conv __P((void *, u_int8_t *, int));
117 1.12.2.2 bouyer
118 1.12.2.2 bouyer struct am7930_glue bba_glue = {
119 1.12.2.2 bouyer bba_codec_iread,
120 1.12.2.2 bouyer bba_codec_iwrite,
121 1.12.2.2 bouyer bba_codec_iread16,
122 1.12.2.2 bouyer bba_codec_iwrite16,
123 1.12.2.2 bouyer bba_onopen,
124 1.12.2.2 bouyer bba_onclose,
125 1.12.2.2 bouyer 4,
126 1.12.2.2 bouyer bba_input_conv,
127 1.12.2.2 bouyer bba_output_conv,
128 1.12.2.2 bouyer };
129 1.12.2.2 bouyer
130 1.12.2.2 bouyer /*
131 1.12.2.2 bouyer * Define our interface to the higher level audio driver.
132 1.12.2.2 bouyer */
133 1.12.2.2 bouyer
134 1.12.2.2 bouyer int bba_round_blocksize __P((void *, int));
135 1.12.2.2 bouyer int bba_halt_output __P((void *));
136 1.12.2.2 bouyer int bba_halt_input __P((void *));
137 1.12.2.2 bouyer int bba_getdev __P((void *, struct audio_device *));
138 1.12.2.2 bouyer void *bba_allocm __P((void *, int, size_t, int, int));
139 1.12.2.2 bouyer void bba_freem __P((void *, void *, int));
140 1.12.2.2 bouyer size_t bba_round_buffersize __P((void *, int, size_t));
141 1.12.2.2 bouyer int bba_get_props __P((void *));
142 1.12.2.2 bouyer paddr_t bba_mappage __P((void *, void *, off_t, int));
143 1.12.2.2 bouyer int bba_trigger_output __P((void *, void *, void *, int,
144 1.12.2.2 bouyer void (*)(void *), void *, struct audio_params *));
145 1.12.2.2 bouyer int bba_trigger_input __P((void *, void *, void *, int,
146 1.12.2.2 bouyer void (*)(void *), void *, struct audio_params *));
147 1.12.2.2 bouyer
148 1.12.2.2 bouyer struct audio_hw_if sa_hw_if = {
149 1.12.2.2 bouyer am7930_open,
150 1.12.2.2 bouyer am7930_close,
151 1.12.2.2 bouyer 0,
152 1.12.2.2 bouyer am7930_query_encoding,
153 1.12.2.2 bouyer am7930_set_params,
154 1.12.2.2 bouyer bba_round_blocksize, /* md */
155 1.12.2.2 bouyer am7930_commit_settings,
156 1.12.2.2 bouyer 0,
157 1.12.2.2 bouyer 0,
158 1.12.2.2 bouyer 0,
159 1.12.2.2 bouyer 0,
160 1.12.2.2 bouyer bba_halt_output, /* md */
161 1.12.2.2 bouyer bba_halt_input, /* md */
162 1.12.2.2 bouyer 0,
163 1.12.2.2 bouyer bba_getdev,
164 1.12.2.2 bouyer 0,
165 1.12.2.2 bouyer am7930_set_port,
166 1.12.2.2 bouyer am7930_get_port,
167 1.12.2.2 bouyer am7930_query_devinfo,
168 1.12.2.2 bouyer bba_allocm, /* md */
169 1.12.2.2 bouyer bba_freem, /* md */
170 1.12.2.2 bouyer bba_round_buffersize, /* md */
171 1.12.2.2 bouyer bba_mappage,
172 1.12.2.2 bouyer bba_get_props,
173 1.12.2.2 bouyer bba_trigger_output, /* md */
174 1.12.2.2 bouyer bba_trigger_input /* md */
175 1.12.2.2 bouyer };
176 1.12.2.2 bouyer
177 1.12.2.2 bouyer struct audio_device bba_device = {
178 1.12.2.2 bouyer "am7930",
179 1.12.2.2 bouyer "x",
180 1.12.2.2 bouyer "bba"
181 1.12.2.2 bouyer };
182 1.12.2.2 bouyer
183 1.12.2.2 bouyer int bba_intr __P((void *));
184 1.12.2.2 bouyer void bba_reset __P((struct bba_softc *, int));
185 1.12.2.2 bouyer void bba_codec_dwrite __P((struct am7930_softc *, int, u_int8_t));
186 1.12.2.2 bouyer u_int8_t bba_codec_dread __P((struct am7930_softc *, int));
187 1.12.2.2 bouyer
188 1.12.2.2 bouyer int bba_match(parent, cf, aux)
189 1.12.2.2 bouyer struct device *parent;
190 1.12.2.2 bouyer struct cfdata *cf;
191 1.12.2.2 bouyer void *aux;
192 1.12.2.2 bouyer {
193 1.12.2.2 bouyer struct ioasicdev_attach_args *ia = aux;
194 1.12.2.2 bouyer
195 1.12.2.2 bouyer if (strcmp(ia->iada_modname, "isdn") != 0 &&
196 1.12.2.2 bouyer strcmp(ia->iada_modname, "AMD79c30") != 0)
197 1.12.2.2 bouyer return 0;
198 1.12.2.2 bouyer
199 1.12.2.2 bouyer return 1;
200 1.12.2.2 bouyer }
201 1.12.2.2 bouyer
202 1.12.2.2 bouyer
203 1.12.2.2 bouyer void
204 1.12.2.2 bouyer bba_attach(parent, self, aux)
205 1.12.2.2 bouyer struct device *parent;
206 1.12.2.2 bouyer struct device *self;
207 1.12.2.2 bouyer void *aux;
208 1.12.2.2 bouyer {
209 1.12.2.2 bouyer struct ioasicdev_attach_args *ia = aux;
210 1.12.2.2 bouyer struct bba_softc *sc = (struct bba_softc *)self;
211 1.12.2.2 bouyer struct am7930_softc *asc = &sc->sc_am7930;
212 1.12.2.2 bouyer
213 1.12.2.2 bouyer sc->sc_bst = ((struct ioasic_softc *)parent)->sc_bst;
214 1.12.2.2 bouyer sc->sc_bsh = ((struct ioasic_softc *)parent)->sc_bsh;
215 1.12.2.2 bouyer sc->sc_dmat = ((struct ioasic_softc *)parent)->sc_dmat;
216 1.12.2.2 bouyer
217 1.12.2.2 bouyer /* get the bus space handle for codec */
218 1.12.2.2 bouyer if (bus_space_subregion(sc->sc_bst, sc->sc_bsh,
219 1.12.2.2 bouyer ia->iada_offset, 0, &sc->sc_codec_bsh)) {
220 1.12.2.2 bouyer printf("%s: unable to map device\n", asc->sc_dev.dv_xname);
221 1.12.2.2 bouyer return;
222 1.12.2.2 bouyer }
223 1.12.2.2 bouyer
224 1.12.2.2 bouyer printf("\n");
225 1.12.2.2 bouyer
226 1.12.2.2 bouyer bba_reset(sc,1);
227 1.12.2.2 bouyer
228 1.12.2.2 bouyer /*
229 1.12.2.2 bouyer * Set up glue for MI code early; we use some of it here.
230 1.12.2.2 bouyer */
231 1.12.2.2 bouyer asc->sc_glue = &bba_glue;
232 1.12.2.2 bouyer
233 1.12.2.2 bouyer /*
234 1.12.2.2 bouyer * MI initialisation. We will be doing DMA.
235 1.12.2.2 bouyer */
236 1.12.2.2 bouyer am7930_init(asc, AUDIOAMD_DMA_MODE);
237 1.12.2.2 bouyer
238 1.12.2.2 bouyer ioasic_intr_establish(parent, ia->iada_cookie, TC_IPL_NONE,
239 1.12.2.2 bouyer bba_intr, sc);
240 1.12.2.2 bouyer
241 1.12.2.2 bouyer audio_attach_mi(&sa_hw_if, asc, &asc->sc_dev);
242 1.12.2.2 bouyer }
243 1.12.2.2 bouyer
244 1.12.2.2 bouyer
245 1.12.2.2 bouyer void
246 1.12.2.2 bouyer bba_onopen(sc)
247 1.12.2.2 bouyer struct am7930_softc *sc;
248 1.12.2.2 bouyer {
249 1.12.2.2 bouyer bba_reset((struct bba_softc *)sc, 0);
250 1.12.2.2 bouyer }
251 1.12.2.2 bouyer
252 1.12.2.2 bouyer
253 1.12.2.2 bouyer void
254 1.12.2.2 bouyer bba_onclose(sc)
255 1.12.2.2 bouyer struct am7930_softc *sc;
256 1.12.2.2 bouyer {
257 1.12.2.2 bouyer bba_halt_input((struct bba_softc *)sc);
258 1.12.2.2 bouyer bba_halt_output((struct bba_softc *)sc);
259 1.12.2.2 bouyer }
260 1.12.2.2 bouyer
261 1.12.2.2 bouyer
262 1.12.2.2 bouyer void
263 1.12.2.2 bouyer bba_reset(sc, reset)
264 1.12.2.2 bouyer struct bba_softc *sc;
265 1.12.2.2 bouyer int reset;
266 1.12.2.2 bouyer {
267 1.12.2.2 bouyer u_int32_t ssr;
268 1.12.2.2 bouyer
269 1.12.2.2 bouyer /* disable any DMA and reset the codec */
270 1.12.2.2 bouyer ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
271 1.12.2.2 bouyer ssr &= ~(IOASIC_CSR_DMAEN_ISDN_T | IOASIC_CSR_DMAEN_ISDN_R);
272 1.12.2.2 bouyer if (reset)
273 1.12.2.2 bouyer ssr &= ~IOASIC_CSR_ISDN_ENABLE;
274 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
275 1.12.2.2 bouyer DELAY(10); /* 400ns required for codec to reset */
276 1.12.2.2 bouyer
277 1.12.2.2 bouyer /* initialise DMA pointers */
278 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_DMAPTR, -1);
279 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_NEXTPTR, -1);
280 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_DMAPTR, -1);
281 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_NEXTPTR, -1);
282 1.12.2.2 bouyer
283 1.12.2.2 bouyer /* take out of reset state */
284 1.12.2.2 bouyer if (reset) {
285 1.12.2.2 bouyer ssr |= IOASIC_CSR_ISDN_ENABLE;
286 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
287 1.12.2.2 bouyer }
288 1.12.2.2 bouyer
289 1.12.2.2 bouyer }
290 1.12.2.2 bouyer
291 1.12.2.2 bouyer
292 1.12.2.2 bouyer void *
293 1.12.2.2 bouyer bba_allocm(addr, direction, size, pool, flags)
294 1.12.2.2 bouyer void *addr;
295 1.12.2.2 bouyer int direction;
296 1.12.2.2 bouyer size_t size;
297 1.12.2.2 bouyer int pool, flags;
298 1.12.2.2 bouyer {
299 1.12.2.2 bouyer struct am7930_softc *asc = addr;
300 1.12.2.2 bouyer struct bba_softc *sc = addr;
301 1.12.2.2 bouyer bus_dma_segment_t seg;
302 1.12.2.2 bouyer int rseg;
303 1.12.2.2 bouyer caddr_t kva;
304 1.12.2.2 bouyer struct bba_mem *m;
305 1.12.2.2 bouyer int w;
306 1.12.2.2 bouyer int state = 0;
307 1.12.2.2 bouyer
308 1.12.2.2 bouyer DPRINTF(("bba_allocm: size = %d\n",size));
309 1.12.2.2 bouyer
310 1.12.2.2 bouyer w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
311 1.12.2.2 bouyer
312 1.12.2.2 bouyer if (bus_dmamem_alloc(sc->sc_dmat, size, BBA_DMABUF_ALIGN,
313 1.12.2.2 bouyer BBA_DMABUF_BOUNDARY, &seg, 1, &rseg, w)) {
314 1.12.2.2 bouyer printf("%s: can't allocate DMA buffer\n",
315 1.12.2.2 bouyer asc->sc_dev.dv_xname);
316 1.12.2.2 bouyer goto bad;
317 1.12.2.2 bouyer }
318 1.12.2.2 bouyer state |= 1;
319 1.12.2.2 bouyer
320 1.12.2.2 bouyer if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
321 1.12.2.2 bouyer &kva, w | BUS_DMA_COHERENT)) {
322 1.12.2.2 bouyer printf("%s: can't map DMA buffer\n", asc->sc_dev.dv_xname);
323 1.12.2.2 bouyer goto bad;
324 1.12.2.2 bouyer }
325 1.12.2.2 bouyer state |= 2;
326 1.12.2.2 bouyer
327 1.12.2.2 bouyer m = malloc(sizeof(struct bba_mem), pool, flags);
328 1.12.2.2 bouyer if (m == NULL)
329 1.12.2.2 bouyer goto bad;
330 1.12.2.2 bouyer m->addr = seg.ds_addr;
331 1.12.2.2 bouyer m->size = seg.ds_len;
332 1.12.2.2 bouyer m->kva = kva;
333 1.12.2.2 bouyer m->next = sc->sc_mem_head;
334 1.12.2.2 bouyer sc->sc_mem_head = m;
335 1.12.2.2 bouyer
336 1.12.2.2 bouyer return (void *)kva;
337 1.12.2.2 bouyer
338 1.12.2.2 bouyer bad:
339 1.12.2.2 bouyer if (state & 2)
340 1.12.2.2 bouyer bus_dmamem_unmap(sc->sc_dmat, kva, size);
341 1.12.2.2 bouyer if (state & 1)
342 1.12.2.2 bouyer bus_dmamem_free(sc->sc_dmat, &seg, 1);
343 1.12.2.2 bouyer return NULL;
344 1.12.2.2 bouyer }
345 1.12.2.2 bouyer
346 1.12.2.2 bouyer
347 1.12.2.2 bouyer void
348 1.12.2.2 bouyer bba_freem(addr, ptr, pool)
349 1.12.2.2 bouyer void *addr;
350 1.12.2.2 bouyer void *ptr;
351 1.12.2.2 bouyer int pool;
352 1.12.2.2 bouyer {
353 1.12.2.2 bouyer struct bba_softc *sc = addr;
354 1.12.2.2 bouyer struct bba_mem **mp, *m;
355 1.12.2.2 bouyer bus_dma_segment_t seg;
356 1.12.2.2 bouyer caddr_t kva = (caddr_t)addr;
357 1.12.2.2 bouyer
358 1.12.2.2 bouyer for (mp = &sc->sc_mem_head; *mp && (*mp)->kva != kva;
359 1.12.2.2 bouyer mp = &(*mp)->next)
360 1.12.2.2 bouyer /* nothing */ ;
361 1.12.2.2 bouyer m = *mp;
362 1.12.2.2 bouyer if (m == NULL) {
363 1.12.2.2 bouyer printf("bba_freem: freeing unallocated memory\n");
364 1.12.2.2 bouyer return;
365 1.12.2.2 bouyer }
366 1.12.2.2 bouyer *mp = m->next;
367 1.12.2.2 bouyer bus_dmamem_unmap(sc->sc_dmat, kva, m->size);
368 1.12.2.2 bouyer
369 1.12.2.2 bouyer seg.ds_addr = m->addr;
370 1.12.2.2 bouyer seg.ds_len = m->size;
371 1.12.2.2 bouyer bus_dmamem_free(sc->sc_dmat, &seg, 1);
372 1.12.2.2 bouyer free(m, pool);
373 1.12.2.2 bouyer }
374 1.12.2.2 bouyer
375 1.12.2.2 bouyer
376 1.12.2.2 bouyer size_t
377 1.12.2.2 bouyer bba_round_buffersize(addr, direction, size)
378 1.12.2.2 bouyer void *addr;
379 1.12.2.2 bouyer int direction;
380 1.12.2.2 bouyer size_t size;
381 1.12.2.2 bouyer {
382 1.12.2.2 bouyer DPRINTF(("bba_round_buffersize: size=%d\n", size));
383 1.12.2.2 bouyer
384 1.12.2.2 bouyer return (size > BBA_DMABUF_SIZE ? BBA_DMABUF_SIZE :
385 1.12.2.2 bouyer roundup(size, IOASIC_DMA_BLOCKSIZE));
386 1.12.2.2 bouyer }
387 1.12.2.2 bouyer
388 1.12.2.2 bouyer
389 1.12.2.2 bouyer int
390 1.12.2.2 bouyer bba_halt_output(addr)
391 1.12.2.2 bouyer void *addr;
392 1.12.2.2 bouyer {
393 1.12.2.2 bouyer struct bba_softc *sc = addr;
394 1.12.2.2 bouyer struct bba_dma_state *d = &sc->sc_tx_dma_state;
395 1.12.2.2 bouyer u_int32_t ssr;
396 1.12.2.2 bouyer
397 1.12.2.2 bouyer /* disable any DMA */
398 1.12.2.2 bouyer ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
399 1.12.2.2 bouyer ssr &= ~IOASIC_CSR_DMAEN_ISDN_T;
400 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
401 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_DMAPTR, -1);
402 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_NEXTPTR, -1);
403 1.12.2.2 bouyer
404 1.12.2.2 bouyer if (d->active) {
405 1.12.2.2 bouyer bus_dmamap_unload(sc->sc_dmat, d->dmam);
406 1.12.2.2 bouyer bus_dmamap_destroy(sc->sc_dmat, d->dmam);
407 1.12.2.2 bouyer d->active = 0;
408 1.12.2.2 bouyer }
409 1.12.2.2 bouyer
410 1.12.2.2 bouyer return 0;
411 1.12.2.2 bouyer }
412 1.12.2.2 bouyer
413 1.12.2.2 bouyer
414 1.12.2.2 bouyer int
415 1.12.2.2 bouyer bba_halt_input(addr)
416 1.12.2.2 bouyer void *addr;
417 1.12.2.2 bouyer {
418 1.12.2.2 bouyer struct bba_softc *sc = addr;
419 1.12.2.2 bouyer struct bba_dma_state *d = &sc->sc_rx_dma_state;
420 1.12.2.2 bouyer u_int32_t ssr;
421 1.12.2.2 bouyer
422 1.12.2.2 bouyer /* disable any DMA */
423 1.12.2.2 bouyer ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
424 1.12.2.2 bouyer ssr &= ~IOASIC_CSR_DMAEN_ISDN_R;
425 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
426 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_DMAPTR, -1);
427 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_NEXTPTR, -1);
428 1.12.2.2 bouyer
429 1.12.2.2 bouyer if (d->active) {
430 1.12.2.2 bouyer bus_dmamap_unload(sc->sc_dmat, d->dmam);
431 1.12.2.2 bouyer bus_dmamap_destroy(sc->sc_dmat, d->dmam);
432 1.12.2.2 bouyer d->active = 0;
433 1.12.2.2 bouyer }
434 1.12.2.2 bouyer
435 1.12.2.2 bouyer return 0;
436 1.12.2.2 bouyer }
437 1.12.2.2 bouyer
438 1.12.2.2 bouyer
439 1.12.2.2 bouyer int
440 1.12.2.2 bouyer bba_getdev(addr, retp)
441 1.12.2.2 bouyer void *addr;
442 1.12.2.2 bouyer struct audio_device *retp;
443 1.12.2.2 bouyer {
444 1.12.2.2 bouyer *retp = bba_device;
445 1.12.2.2 bouyer return 0;
446 1.12.2.2 bouyer }
447 1.12.2.2 bouyer
448 1.12.2.2 bouyer
449 1.12.2.2 bouyer int
450 1.12.2.2 bouyer bba_trigger_output(addr, start, end, blksize, intr, arg, param)
451 1.12.2.2 bouyer void *addr;
452 1.12.2.2 bouyer void *start, *end;
453 1.12.2.2 bouyer int blksize;
454 1.12.2.2 bouyer void (*intr) __P((void *));
455 1.12.2.2 bouyer void *arg;
456 1.12.2.2 bouyer struct audio_params *param;
457 1.12.2.2 bouyer {
458 1.12.2.2 bouyer struct bba_softc *sc = addr;
459 1.12.2.2 bouyer struct bba_dma_state *d = &sc->sc_tx_dma_state;
460 1.12.2.2 bouyer u_int32_t ssr;
461 1.12.2.2 bouyer tc_addr_t phys, nphys;
462 1.12.2.2 bouyer int state = 0;
463 1.12.2.2 bouyer
464 1.12.2.2 bouyer DPRINTF(("bba_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
465 1.12.2.2 bouyer addr, start, end, blksize, intr, arg));
466 1.12.2.2 bouyer
467 1.12.2.2 bouyer /* disable any DMA */
468 1.12.2.2 bouyer ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
469 1.12.2.2 bouyer ssr &= ~IOASIC_CSR_DMAEN_ISDN_T;
470 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
471 1.12.2.2 bouyer
472 1.12.2.2 bouyer if (bus_dmamap_create(sc->sc_dmat, (char *)end - (char *)start,
473 1.12.2.2 bouyer BBA_MAX_DMA_SEGMENTS, IOASIC_DMA_BLOCKSIZE,
474 1.12.2.2 bouyer BBA_DMABUF_BOUNDARY, BUS_DMA_NOWAIT, &d->dmam)) {
475 1.12.2.2 bouyer printf("bba_trigger_output: can't create DMA map\n");
476 1.12.2.2 bouyer goto bad;
477 1.12.2.2 bouyer }
478 1.12.2.2 bouyer state |= 1;
479 1.12.2.2 bouyer
480 1.12.2.2 bouyer if (bus_dmamap_load(sc->sc_dmat, d->dmam, start,
481 1.12.2.2 bouyer (char *)end - (char *)start, NULL, BUS_DMA_NOWAIT)) {
482 1.12.2.2 bouyer printf("bba_trigger_output: can't load DMA map\n");
483 1.12.2.2 bouyer goto bad;
484 1.12.2.2 bouyer }
485 1.12.2.2 bouyer state |= 2;
486 1.12.2.2 bouyer
487 1.12.2.2 bouyer d->intr = intr;
488 1.12.2.2 bouyer d->intr_arg = arg;
489 1.12.2.2 bouyer d->curseg = 1;
490 1.12.2.2 bouyer
491 1.12.2.2 bouyer /* get physical address of buffer start */
492 1.12.2.2 bouyer phys = (tc_addr_t)d->dmam->dm_segs[0].ds_addr;
493 1.12.2.2 bouyer nphys = (tc_addr_t)d->dmam->dm_segs[1].ds_addr;
494 1.12.2.2 bouyer
495 1.12.2.2 bouyer /* setup DMA pointer */
496 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_DMAPTR,
497 1.12.2.2 bouyer IOASIC_DMA_ADDR(phys));
498 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_NEXTPTR,
499 1.12.2.2 bouyer IOASIC_DMA_ADDR(nphys));
500 1.12.2.2 bouyer
501 1.12.2.2 bouyer /* kick off DMA */
502 1.12.2.2 bouyer ssr |= IOASIC_CSR_DMAEN_ISDN_T;
503 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
504 1.12.2.2 bouyer
505 1.12.2.2 bouyer d->active = 1;
506 1.12.2.2 bouyer
507 1.12.2.2 bouyer return 0;
508 1.12.2.2 bouyer
509 1.12.2.2 bouyer bad:
510 1.12.2.2 bouyer if (state & 2)
511 1.12.2.2 bouyer bus_dmamap_unload(sc->sc_dmat, d->dmam);
512 1.12.2.2 bouyer if (state & 1)
513 1.12.2.2 bouyer bus_dmamap_destroy(sc->sc_dmat, d->dmam);
514 1.12.2.2 bouyer return 1;
515 1.12.2.2 bouyer }
516 1.12.2.2 bouyer
517 1.12.2.2 bouyer
518 1.12.2.2 bouyer int
519 1.12.2.2 bouyer bba_trigger_input(addr, start, end, blksize, intr, arg, param)
520 1.12.2.2 bouyer void *addr;
521 1.12.2.2 bouyer void *start, *end;
522 1.12.2.2 bouyer int blksize;
523 1.12.2.2 bouyer void (*intr) __P((void *));
524 1.12.2.2 bouyer void *arg;
525 1.12.2.2 bouyer struct audio_params *param;
526 1.12.2.2 bouyer {
527 1.12.2.2 bouyer struct bba_softc *sc = (struct bba_softc *)addr;
528 1.12.2.2 bouyer struct bba_dma_state *d = &sc->sc_rx_dma_state;
529 1.12.2.2 bouyer tc_addr_t phys, nphys;
530 1.12.2.2 bouyer u_int32_t ssr;
531 1.12.2.2 bouyer int state = 0;
532 1.12.2.2 bouyer
533 1.12.2.2 bouyer DPRINTF(("bba_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
534 1.12.2.2 bouyer addr, start, end, blksize, intr, arg));
535 1.12.2.2 bouyer
536 1.12.2.2 bouyer /* disable any DMA */
537 1.12.2.2 bouyer ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
538 1.12.2.2 bouyer ssr &= ~IOASIC_CSR_DMAEN_ISDN_R;
539 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
540 1.12.2.2 bouyer
541 1.12.2.2 bouyer if (bus_dmamap_create(sc->sc_dmat, (char *)end - (char *)start,
542 1.12.2.2 bouyer BBA_MAX_DMA_SEGMENTS, IOASIC_DMA_BLOCKSIZE,
543 1.12.2.2 bouyer BBA_DMABUF_BOUNDARY, BUS_DMA_NOWAIT, &d->dmam)) {
544 1.12.2.2 bouyer printf("bba_trigger_input: can't create DMA map\n");
545 1.12.2.2 bouyer goto bad;
546 1.12.2.2 bouyer }
547 1.12.2.2 bouyer state |= 1;
548 1.12.2.2 bouyer
549 1.12.2.2 bouyer if (bus_dmamap_load(sc->sc_dmat, d->dmam, start,
550 1.12.2.2 bouyer (char *)end - (char *)start, NULL, BUS_DMA_NOWAIT)) {
551 1.12.2.2 bouyer printf("bba_trigger_input: can't load DMA map\n");
552 1.12.2.2 bouyer goto bad;
553 1.12.2.2 bouyer }
554 1.12.2.2 bouyer state |= 2;
555 1.12.2.2 bouyer
556 1.12.2.2 bouyer d->intr = intr;
557 1.12.2.2 bouyer d->intr_arg = arg;
558 1.12.2.2 bouyer d->curseg = 1;
559 1.12.2.2 bouyer
560 1.12.2.2 bouyer /* get physical address of buffer start */
561 1.12.2.2 bouyer phys = (tc_addr_t)d->dmam->dm_segs[0].ds_addr;
562 1.12.2.2 bouyer nphys = (tc_addr_t)d->dmam->dm_segs[1].ds_addr;
563 1.12.2.2 bouyer
564 1.12.2.2 bouyer /* setup DMA pointer */
565 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_DMAPTR,
566 1.12.2.2 bouyer IOASIC_DMA_ADDR(phys));
567 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_NEXTPTR,
568 1.12.2.2 bouyer IOASIC_DMA_ADDR(nphys));
569 1.12.2.2 bouyer
570 1.12.2.2 bouyer /* kick off DMA */
571 1.12.2.2 bouyer ssr |= IOASIC_CSR_DMAEN_ISDN_R;
572 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
573 1.12.2.2 bouyer
574 1.12.2.2 bouyer d->active = 1;
575 1.12.2.2 bouyer
576 1.12.2.2 bouyer return 0;
577 1.12.2.2 bouyer
578 1.12.2.2 bouyer bad:
579 1.12.2.2 bouyer if (state & 2)
580 1.12.2.2 bouyer bus_dmamap_unload(sc->sc_dmat, d->dmam);
581 1.12.2.2 bouyer if (state & 1)
582 1.12.2.2 bouyer bus_dmamap_destroy(sc->sc_dmat, d->dmam);
583 1.12.2.2 bouyer return 1;
584 1.12.2.2 bouyer }
585 1.12.2.2 bouyer
586 1.12.2.2 bouyer int
587 1.12.2.2 bouyer bba_intr(addr)
588 1.12.2.2 bouyer void *addr;
589 1.12.2.2 bouyer {
590 1.12.2.2 bouyer struct bba_softc *sc = addr;
591 1.12.2.2 bouyer struct bba_dma_state *d;
592 1.12.2.2 bouyer tc_addr_t nphys;
593 1.12.2.2 bouyer int s, mask;
594 1.12.2.2 bouyer
595 1.12.2.2 bouyer s = splaudio();
596 1.12.2.2 bouyer
597 1.12.2.2 bouyer mask = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_INTR);
598 1.12.2.2 bouyer
599 1.12.2.2 bouyer if (mask & IOASIC_INTR_ISDN_TXLOAD) {
600 1.12.2.2 bouyer d = &sc->sc_tx_dma_state;
601 1.12.2.2 bouyer d->curseg = (d->curseg+1) % d->dmam->dm_nsegs;
602 1.12.2.2 bouyer nphys = (tc_addr_t)d->dmam->dm_segs[d->curseg].ds_addr;
603 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh,
604 1.12.2.2 bouyer IOASIC_ISDN_X_NEXTPTR, IOASIC_DMA_ADDR(nphys));
605 1.12.2.2 bouyer if (d->intr != NULL)
606 1.12.2.2 bouyer (*d->intr)(d->intr_arg);
607 1.12.2.2 bouyer }
608 1.12.2.2 bouyer if (mask & IOASIC_INTR_ISDN_RXLOAD) {
609 1.12.2.2 bouyer d = &sc->sc_rx_dma_state;
610 1.12.2.2 bouyer d->curseg = (d->curseg+1) % d->dmam->dm_nsegs;
611 1.12.2.2 bouyer nphys = (tc_addr_t)d->dmam->dm_segs[d->curseg].ds_addr;
612 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_bsh,
613 1.12.2.2 bouyer IOASIC_ISDN_R_NEXTPTR, IOASIC_DMA_ADDR(nphys));
614 1.12.2.2 bouyer if (d->intr != NULL)
615 1.12.2.2 bouyer (*d->intr)(d->intr_arg);
616 1.12.2.2 bouyer }
617 1.12.2.2 bouyer
618 1.12.2.2 bouyer splx(s);
619 1.12.2.2 bouyer
620 1.12.2.2 bouyer return 0;
621 1.12.2.2 bouyer }
622 1.12.2.2 bouyer
623 1.12.2.2 bouyer int
624 1.12.2.2 bouyer bba_get_props(addr)
625 1.12.2.2 bouyer void *addr;
626 1.12.2.2 bouyer {
627 1.12.2.2 bouyer return (AUDIO_PROP_MMAP | am7930_get_props(addr));
628 1.12.2.2 bouyer }
629 1.12.2.2 bouyer
630 1.12.2.2 bouyer paddr_t
631 1.12.2.2 bouyer bba_mappage(addr, mem, offset, prot)
632 1.12.2.2 bouyer void *addr;
633 1.12.2.2 bouyer void *mem;
634 1.12.2.2 bouyer off_t offset;
635 1.12.2.2 bouyer int prot;
636 1.12.2.2 bouyer {
637 1.12.2.2 bouyer struct bba_softc *sc = addr;
638 1.12.2.2 bouyer struct bba_mem **mp;
639 1.12.2.2 bouyer bus_dma_segment_t seg;
640 1.12.2.2 bouyer caddr_t kva = (caddr_t)mem;
641 1.12.2.2 bouyer
642 1.12.2.2 bouyer for (mp = &sc->sc_mem_head; *mp && (*mp)->kva != kva;
643 1.12.2.2 bouyer mp = &(*mp)->next)
644 1.12.2.2 bouyer /* nothing */ ;
645 1.12.2.2 bouyer if (*mp == NULL || offset < 0) {
646 1.12.2.2 bouyer return -1;
647 1.12.2.2 bouyer }
648 1.12.2.2 bouyer
649 1.12.2.2 bouyer seg.ds_addr = (*mp)->addr;
650 1.12.2.2 bouyer seg.ds_len = (*mp)->size;
651 1.12.2.2 bouyer
652 1.12.2.2 bouyer return bus_dmamem_mmap(sc->sc_dmat, &seg, 1, offset,
653 1.12.2.2 bouyer prot, BUS_DMA_WAITOK);
654 1.12.2.2 bouyer }
655 1.12.2.2 bouyer
656 1.12.2.2 bouyer
657 1.12.2.2 bouyer void
658 1.12.2.2 bouyer bba_input_conv(v, p, cc)
659 1.12.2.2 bouyer void *v;
660 1.12.2.2 bouyer u_int8_t *p;
661 1.12.2.2 bouyer int cc;
662 1.12.2.2 bouyer {
663 1.12.2.2 bouyer u_int8_t *q = p;
664 1.12.2.2 bouyer
665 1.12.2.2 bouyer DPRINTF(("bba_input_conv(): v=%p p=%p cc=%d\n", v, p, cc));
666 1.12.2.2 bouyer
667 1.12.2.2 bouyer /*
668 1.12.2.2 bouyer * p points start of buffer
669 1.12.2.2 bouyer * cc is the number of bytes in the destination buffer
670 1.12.2.2 bouyer */
671 1.12.2.2 bouyer
672 1.12.2.2 bouyer while (--cc >= 0) {
673 1.12.2.2 bouyer *p = ((*(u_int32_t *)q)>>16)&0xff;
674 1.12.2.2 bouyer q += 4;
675 1.12.2.2 bouyer p++;
676 1.12.2.2 bouyer }
677 1.12.2.2 bouyer }
678 1.12.2.2 bouyer
679 1.12.2.2 bouyer
680 1.12.2.2 bouyer void
681 1.12.2.2 bouyer bba_output_conv(v, p, cc)
682 1.12.2.2 bouyer void *v;
683 1.12.2.2 bouyer u_int8_t *p;
684 1.12.2.2 bouyer int cc;
685 1.12.2.2 bouyer {
686 1.12.2.2 bouyer u_int8_t *q = p;
687 1.12.2.2 bouyer
688 1.12.2.2 bouyer DPRINTF(("bba_output_conv(): v=%p p=%p cc=%d\n", v, p, cc));
689 1.12.2.2 bouyer
690 1.12.2.2 bouyer /*
691 1.12.2.2 bouyer * p points start of buffer
692 1.12.2.2 bouyer * cc is the number of bytes in the source buffer
693 1.12.2.2 bouyer */
694 1.12.2.2 bouyer
695 1.12.2.2 bouyer p += cc;
696 1.12.2.2 bouyer q += cc * 4;
697 1.12.2.2 bouyer while (--cc >= 0) {
698 1.12.2.2 bouyer q -= 4;
699 1.12.2.2 bouyer p -= 1;
700 1.12.2.2 bouyer *(u_int32_t *)q = (*p<<16);
701 1.12.2.2 bouyer }
702 1.12.2.2 bouyer }
703 1.12.2.2 bouyer
704 1.12.2.2 bouyer
705 1.12.2.2 bouyer int
706 1.12.2.2 bouyer bba_round_blocksize(addr, blk)
707 1.12.2.2 bouyer void *addr;
708 1.12.2.2 bouyer int blk;
709 1.12.2.2 bouyer {
710 1.12.2.2 bouyer return (IOASIC_DMA_BLOCKSIZE);
711 1.12.2.2 bouyer }
712 1.12.2.2 bouyer
713 1.12.2.2 bouyer
714 1.12.2.2 bouyer /* indirect write */
715 1.12.2.2 bouyer void
716 1.12.2.2 bouyer bba_codec_iwrite(sc, reg, val)
717 1.12.2.2 bouyer struct am7930_softc *sc;
718 1.12.2.2 bouyer int reg;
719 1.12.2.2 bouyer u_int8_t val;
720 1.12.2.2 bouyer {
721 1.12.2.2 bouyer DPRINTF(("bba_codec_iwrite(): sc=%p, reg=%d, val=%d\n",sc,reg,val));
722 1.12.2.2 bouyer
723 1.12.2.2 bouyer bba_codec_dwrite(sc, AM7930_DREG_CR, reg);
724 1.12.2.2 bouyer bba_codec_dwrite(sc, AM7930_DREG_DR, val);
725 1.12.2.2 bouyer }
726 1.12.2.2 bouyer
727 1.12.2.2 bouyer
728 1.12.2.2 bouyer void
729 1.12.2.2 bouyer bba_codec_iwrite16(sc, reg, val)
730 1.12.2.2 bouyer struct am7930_softc *sc;
731 1.12.2.2 bouyer int reg;
732 1.12.2.2 bouyer u_int16_t val;
733 1.12.2.2 bouyer {
734 1.12.2.2 bouyer DPRINTF(("bba_codec_iwrite16(): sc=%p, reg=%d, val=%d\n",sc,reg,val));
735 1.12.2.2 bouyer
736 1.12.2.2 bouyer bba_codec_dwrite(sc, AM7930_DREG_CR, reg);
737 1.12.2.2 bouyer bba_codec_dwrite(sc, AM7930_DREG_DR, val);
738 1.12.2.2 bouyer bba_codec_dwrite(sc, AM7930_DREG_DR, val>>8);
739 1.12.2.2 bouyer }
740 1.12.2.2 bouyer
741 1.12.2.2 bouyer
742 1.12.2.2 bouyer u_int16_t
743 1.12.2.2 bouyer bba_codec_iread16(sc, reg)
744 1.12.2.2 bouyer struct am7930_softc *sc;
745 1.12.2.2 bouyer int reg;
746 1.12.2.2 bouyer {
747 1.12.2.2 bouyer u_int16_t val;
748 1.12.2.2 bouyer DPRINTF(("bba_codec_iread16(): sc=%p, reg=%d\n",sc,reg));
749 1.12.2.2 bouyer
750 1.12.2.2 bouyer bba_codec_dwrite(sc, AM7930_DREG_CR, reg);
751 1.12.2.2 bouyer val = bba_codec_dread(sc, AM7930_DREG_DR) << 8;
752 1.12.2.2 bouyer val |= bba_codec_dread(sc, AM7930_DREG_DR);
753 1.12.2.2 bouyer
754 1.12.2.2 bouyer return val;
755 1.12.2.2 bouyer }
756 1.12.2.2 bouyer
757 1.12.2.2 bouyer
758 1.12.2.2 bouyer /* indirect read */
759 1.12.2.2 bouyer u_int8_t
760 1.12.2.2 bouyer bba_codec_iread(sc, reg)
761 1.12.2.2 bouyer struct am7930_softc *sc;
762 1.12.2.2 bouyer int reg;
763 1.12.2.2 bouyer {
764 1.12.2.2 bouyer u_int8_t val;
765 1.12.2.2 bouyer
766 1.12.2.2 bouyer DPRINTF(("bba_codec_iread(): sc=%p, reg=%d\n",sc,reg));
767 1.12.2.2 bouyer
768 1.12.2.2 bouyer bba_codec_dwrite(sc, AM7930_DREG_CR, reg);
769 1.12.2.2 bouyer val = bba_codec_dread(sc, AM7930_DREG_DR);
770 1.12.2.2 bouyer
771 1.12.2.2 bouyer DPRINTF(("read 0x%x (%d)\n", val, val));
772 1.12.2.2 bouyer
773 1.12.2.2 bouyer return val;
774 1.12.2.2 bouyer }
775 1.12.2.2 bouyer
776 1.12.2.2 bouyer /* direct write */
777 1.12.2.2 bouyer void
778 1.12.2.2 bouyer bba_codec_dwrite(asc, reg, val)
779 1.12.2.2 bouyer struct am7930_softc *asc;
780 1.12.2.2 bouyer int reg;
781 1.12.2.2 bouyer u_int8_t val;
782 1.12.2.2 bouyer {
783 1.12.2.2 bouyer struct bba_softc *sc = (struct bba_softc *)asc;
784 1.12.2.2 bouyer
785 1.12.2.2 bouyer DPRINTF(("bba_codec_dwrite(): sc=%p, reg=%d, val=%d\n",sc,reg,val));
786 1.12.2.2 bouyer
787 1.12.2.2 bouyer #if defined(__alpha__)
788 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_codec_bsh,
789 1.12.2.2 bouyer reg << 2, val << 8);
790 1.12.2.2 bouyer #else
791 1.12.2.2 bouyer bus_space_write_4(sc->sc_bst, sc->sc_codec_bsh,
792 1.12.2.2 bouyer reg << 6, val);
793 1.12.2.2 bouyer #endif
794 1.12.2.2 bouyer }
795 1.12.2.2 bouyer
796 1.12.2.2 bouyer /* direct read */
797 1.12.2.2 bouyer u_int8_t
798 1.12.2.2 bouyer bba_codec_dread(asc, reg)
799 1.12.2.2 bouyer struct am7930_softc *asc;
800 1.12.2.2 bouyer int reg;
801 1.12.2.2 bouyer {
802 1.12.2.2 bouyer struct bba_softc *sc = (struct bba_softc *)asc;
803 1.12.2.2 bouyer
804 1.12.2.2 bouyer DPRINTF(("bba_codec_dread(): sc=%p, reg=%d\n",sc,reg));
805 1.12.2.2 bouyer
806 1.12.2.2 bouyer #if defined(__alpha__)
807 1.12.2.2 bouyer return ((bus_space_read_4(sc->sc_bst, sc->sc_codec_bsh,
808 1.12.2.2 bouyer reg << 2) >> 8) & 0xff);
809 1.12.2.2 bouyer #else
810 1.12.2.2 bouyer return (bus_space_read_4(sc->sc_bst, sc->sc_codec_bsh,
811 1.12.2.2 bouyer reg << 6) & 0xff);
812 1.12.2.2 bouyer #endif
813 1.12.2.2 bouyer }
814