dbri.c revision 1.12 1 /* $NetBSD: dbri.c,v 1.12 2007/03/11 08:52:12 macallan Exp $ */
2
3 /*
4 * Copyright (C) 1997 Rudolf Koenig (rfkoenig (at) immd4.informatik.uni-erlangen.de)
5 * Copyright (c) 1998, 1999 Brent Baccala (baccala (at) freesoft.org)
6 * Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill (at) netbsd.org>
7 * Copyright (c) 2005 Michael Lorenz <macallan (at) netbsd.org>
8 * All rights reserved.
9 *
10 * This driver is losely based on a Linux driver written by Rudolf Koenig and
11 * Brent Baccala who kindly gave their permission to use their code in a
12 * BSD-licensed driver.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 * must display the following acknowledgement:
24 * This product includes software developed by Rudolf Koenig, Brent
25 * Baccala, Jared D. McNeill.
26 * 4. Neither the name of the author nor the names of any contributors may
27 * be used to endorse or promote products derived from this software
28 * without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
41 *
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: dbri.c,v 1.12 2007/03/11 08:52:12 macallan Exp $");
46
47 #include "audio.h"
48 #if NAUDIO > 0
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/errno.h>
53 #include <sys/device.h>
54 #include <sys/malloc.h>
55 #include <sys/proc.h>
56
57 #include <machine/bus.h>
58 #include <machine/intr.h>
59
60 #include <dev/sbus/sbusvar.h>
61 #include <sparc/sparc/auxreg.h>
62 #include <machine/autoconf.h>
63
64 #include <sys/audioio.h>
65 #include <dev/audio_if.h>
66 #include <dev/auconv.h>
67
68 #include <dev/ic/cs4215reg.h>
69 #include <dev/ic/cs4215var.h>
70 #include <dev/sbus/dbrireg.h>
71 #include <dev/sbus/dbrivar.h>
72
73 #include "opt_sbus_dbri.h"
74
75 #define DBRI_ROM_NAME_PREFIX "SUNW,DBRI"
76
77 #ifdef DBRI_DEBUG
78 # define DPRINTF aprint_normal
79 #else
80 # define DPRINTF while (0) printf
81 #endif
82
83 static const char *dbri_supported[] = {
84 "e",
85 "s3",
86 ""
87 };
88
89 enum ms {
90 CHImaster,
91 CHIslave
92 };
93
94 enum io {
95 PIPEinput,
96 PIPEoutput
97 };
98
99 /*
100 * Function prototypes
101 */
102
103 /* softc stuff */
104 static void dbri_attach_sbus(struct device *, struct device *, void *);
105 static int dbri_match_sbus(struct device *, struct cfdata *, void *);
106
107 static void dbri_config_interrupts(struct device *);
108
109 /* interrupt handler */
110 static int dbri_intr(void *);
111
112 /* supporting subroutines */
113 static int dbri_init(struct dbri_softc *);
114 static int dbri_reset(struct dbri_softc *);
115 static volatile u_int32_t *dbri_command_lock(struct dbri_softc *);
116 static void dbri_command_send(struct dbri_softc *, volatile u_int32_t *);
117 static void dbri_process_interrupt_buffer(struct dbri_softc *);
118 static void dbri_process_interrupt(struct dbri_softc *, int32_t);
119
120 /* mmcodec subroutines */
121 static int mmcodec_init(struct dbri_softc *);
122 static void mmcodec_init_data(struct dbri_softc *);
123 static void mmcodec_pipe_init(struct dbri_softc *);
124 static void mmcodec_default(struct dbri_softc *);
125 static void mmcodec_setgain(struct dbri_softc *, int);
126 static int mmcodec_setcontrol(struct dbri_softc *);
127
128 /* chi subroutines */
129 static void chi_reset(struct dbri_softc *, enum ms, int);
130
131 /* pipe subroutines */
132 static void pipe_setup(struct dbri_softc *, int, int);
133 static void pipe_reset(struct dbri_softc *, int);
134 static void pipe_receive_fixed(struct dbri_softc *, int,
135 volatile u_int32_t *);
136 static void pipe_transmit_fixed(struct dbri_softc *, int, u_int32_t);
137
138 static void pipe_ts_link(struct dbri_softc *, int, enum io, int, int, int);
139 static int pipe_active(struct dbri_softc *, int);
140
141 /* audio(9) stuff */
142 static int dbri_query_encoding(void *, struct audio_encoding *);
143 static int dbri_set_params(void *, int, int, struct audio_params *,
144 struct audio_params *,stream_filter_list_t *, stream_filter_list_t *);
145 static int dbri_round_blocksize(void *, int, int, const audio_params_t *);
146 static int dbri_halt_output(void *);
147 static int dbri_getdev(void *, struct audio_device *);
148 static int dbri_set_port(void *, mixer_ctrl_t *);
149 static int dbri_get_port(void *, mixer_ctrl_t *);
150 static int dbri_query_devinfo(void *, mixer_devinfo_t *);
151 static size_t dbri_round_buffersize(void *, int, size_t);
152 static int dbri_get_props(void *);
153 static int dbri_open(void *, int);
154 static void dbri_close(void *);
155
156 static void setup_ring(struct dbri_softc *, int, int, int, int,
157 void (*)(void *), void *);
158
159 static int dbri_trigger_output(void *, void *, void *, int,
160 void (*)(void *), void *, const struct audio_params *);
161
162 static void *dbri_malloc(void *, int, size_t, struct malloc_type *, int);
163 static void dbri_free(void *, void *, struct malloc_type *);
164 static paddr_t dbri_mappage(void *, void *, off_t, int);
165 static void dbri_set_power(struct dbri_softc *, int);
166 static void dbri_bring_up(struct dbri_softc *);
167 static void dbri_powerhook(int, void *);
168
169 /* stupid support routines */
170 static u_int32_t reverse_bytes(u_int32_t, int);
171
172 struct audio_device dbri_device = {
173 "CS4215",
174 "",
175 "dbri"
176 };
177
178 struct audio_hw_if dbri_hw_if = {
179 dbri_open,
180 dbri_close,
181 NULL, /* drain */
182 dbri_query_encoding,
183 dbri_set_params,
184 dbri_round_blocksize,
185 NULL, /* commit_settings */
186 NULL, /* init_output */
187 NULL, /* init_input */
188 NULL, /* start_output */
189 NULL, /* start_input */
190 dbri_halt_output,
191 NULL, /* halt_input */
192 NULL, /* speaker_ctl */
193 dbri_getdev,
194 NULL, /* setfd */
195 dbri_set_port,
196 dbri_get_port,
197 dbri_query_devinfo,
198 dbri_malloc,
199 dbri_free,
200 dbri_round_buffersize,
201 dbri_mappage,
202 dbri_get_props,
203 dbri_trigger_output,
204 NULL /* trigger_input */
205 };
206
207 CFATTACH_DECL(dbri, sizeof(struct dbri_softc),
208 dbri_match_sbus, dbri_attach_sbus, NULL, NULL);
209
210 #define DBRI_NFORMATS 7
211 static const struct audio_format dbri_formats[DBRI_NFORMATS] = {
212 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_BE, 16, 16,
213 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000}},
214 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULAW, 8, 8,
215 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000}},
216 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ALAW, 8, 8,
217 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000}},
218 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR, 8, 8,
219 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000}},
220 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULAW, 8, 8,
221 1, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000}},
222 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ALAW, 8, 8,
223 1, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000}},
224 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR, 8, 8,
225 1, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000}},
226 };
227
228 enum {
229 DBRI_MONITOR_CLASS,
230 DBRI_VOL_OUTPUT,
231 DBRI_ENABLE_MONO,
232 DBRI_ENABLE_HEADPHONE,
233 DBRI_ENABLE_LINE
234 /*
235 DBRI_INPUT_CLASS,
236 DBRI_RECORD_CLASS,
237 DBRI_INPUT_GAIN,
238 DBRI_INPUT_SELECT,
239 DBRI_ENUM_LAST
240 */
241 };
242
243 /*
244 * Autoconfig routines
245 */
246 static int
247 dbri_match_sbus(struct device *parent, struct cfdata *match, void *aux)
248 {
249 struct sbus_attach_args *sa = aux;
250 char *ver;
251 int i;
252
253 if (strncmp(DBRI_ROM_NAME_PREFIX, sa->sa_name, 9))
254 return (0);
255
256 ver = &sa->sa_name[9];
257
258 for (i = 0; dbri_supported[i][0] != '\0'; i++)
259 if (strcmp(dbri_supported[i], ver) == 0)
260 return (1);
261
262 return (0);
263 }
264
265 static void
266 dbri_attach_sbus(struct device *parent, struct device *self, void *aux)
267 {
268 struct dbri_softc *sc = (struct dbri_softc *)self;
269 struct sbus_attach_args *sa = aux;
270 bus_space_handle_t ioh;
271 bus_size_t size;
272 int error, rseg, pwr;
273 char *ver = &sa->sa_name[9];
274
275 sc->sc_iot = sa->sa_bustag;
276 sc->sc_dmat = sa->sa_dmatag;
277 sc->sc_powerstate = PWR_RESUME;
278
279 pwr = prom_getpropint(sa->sa_node,"pwr-on-auxio",0);
280 printf(": rev %s\n", ver);
281
282 if (pwr) {
283 /*
284 * we can control DBRI power via auxio and we're initially
285 * powered down
286 */
287
288 sc->sc_have_powerctl = 1;
289 sc->sc_powerstate = 0;
290 dbri_set_power(sc, 1);
291 powerhook_establish(self->dv_xname, dbri_powerhook, sc);
292 } else {
293 /* we can't control power so we're always up */
294 sc->sc_have_powerctl = 0;
295 sc->sc_powerstate = 1;
296 }
297
298 if (sa->sa_npromvaddrs)
299 ioh = (bus_space_handle_t)sa->sa_promvaddrs[0];
300 else {
301 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
302 sa->sa_offset, sa->sa_size,
303 BUS_SPACE_MAP_LINEAR, /*0,*/ &ioh) != 0) {
304 aprint_error("%s @ sbus: cannot map registers\n",
305 self->dv_xname);
306 return;
307 }
308 }
309
310 sc->sc_ioh = ioh;
311
312 size = sizeof(struct dbri_dma);
313
314 /* get a DMA handle */
315 if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
316 BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
317 aprint_error("%s: DMA map create error %d\n", self->dv_xname, error);
318 return;
319 }
320
321 /* allocate DMA buffer */
322 if ((error = bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &sc->sc_dmaseg,
323 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
324 aprint_error("%s: DMA buffer alloc error %d\n",
325 self->dv_xname, error);
326 return;
327 }
328
329 /* map DMA buffer into CPU addressable space */
330 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dmaseg, rseg, size,
331 &sc->sc_membase,
332 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
333 aprint_error("%s: DMA buffer map error %d\n",
334 self->dv_xname, error);
335 return;
336 }
337
338 /* load the buffer */
339 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap,
340 sc->sc_membase, size, NULL,
341 BUS_DMA_NOWAIT)) != 0) {
342 aprint_error("%s: DMA buffer map load error %d\n",
343 self->dv_xname, error);
344 bus_dmamem_unmap(sc->sc_dmat, sc->sc_membase, size);
345 bus_dmamem_free(sc->sc_dmat, &sc->sc_dmaseg, rseg);
346 return;
347 }
348
349 /* map the registers into memory */
350
351 /* kernel virtual address of DMA buffer */
352 sc->sc_dma = (struct dbri_dma *)sc->sc_membase;
353 /* physical address of DMA buffer */
354 sc->sc_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr;
355 sc->sc_bufsiz = size;
356
357 sbus_establish(&sc->sc_sd, &sc->sc_dev);
358
359 bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_AUDIO, dbri_intr,
360 sc);
361
362 sc->sc_locked = 0;
363 sc->sc_desc_used = 0;
364
365 config_interrupts(self, &dbri_config_interrupts);
366
367 return;
368 }
369
370 /*
371 * lowlevel routine to switch power for the DBRI chip
372 */
373 static void
374 dbri_set_power(struct dbri_softc *sc, int state)
375 {
376 int s;
377
378 if (sc->sc_have_powerctl == 0)
379 return;
380 if (sc->sc_powerstate == state)
381 return;
382
383 if (state) {
384 DPRINTF("%s: waiting to power up... ", sc->sc_dev.dv_xname);
385 s = splhigh();
386 *AUXIO4M_REG |= (AUXIO4M_MMX);
387 splx(s);
388 delay(10000);
389 DPRINTF("done (%02x})\n", *AUXIO4M_REG);
390 } else {
391 DPRINTF("%s: powering down\n", sc->sc_dev.dv_xname);
392 s = splhigh();
393 *AUXIO4M_REG &= ~AUXIO4M_MMX;
394 splx(s);
395 DPRINTF("done (%02x})\n", *AUXIO4M_REG);
396 }
397 sc->sc_powerstate = state;
398 }
399
400 /*
401 * power up and re-initialize the chip
402 */
403 static void
404 dbri_bring_up(struct dbri_softc *sc)
405 {
406
407 if (sc->sc_have_powerctl == 0)
408 return;
409 if (sc->sc_powerstate == 1)
410 return;
411
412 /* ok, we really need to do something */
413 dbri_set_power(sc, 1);
414
415 /*
416 * re-initialize the chip but skip all the probing, don't overwrite
417 * any other settings either
418 */
419 dbri_init(sc);
420 mmcodec_setgain(sc, 1);
421 mmcodec_pipe_init(sc);
422 mmcodec_init_data(sc);
423 mmcodec_setgain(sc, 0);
424 }
425
426 static void
427 dbri_config_interrupts(struct device *dev)
428 {
429 struct dbri_softc *sc = (struct dbri_softc *)dev;
430
431 dbri_init(sc);
432 mmcodec_init(sc);
433
434 /* Attach ourselves to the high level audio interface */
435 audio_attach_mi(&dbri_hw_if, sc, &sc->sc_dev);
436
437 /* power down until open() */
438 dbri_set_power(sc, 0);
439 return;
440 }
441
442 static int
443 dbri_intr(void *hdl)
444 {
445 struct dbri_softc *sc = hdl;
446 bus_space_tag_t iot = sc->sc_iot;
447 bus_space_handle_t ioh = sc->sc_ioh;
448 int x;
449
450 /* clear interrupt */
451 x = bus_space_read_4(iot, ioh, DBRI_REG1);
452 if (x & (DBRI_MRR | DBRI_MLE | DBRI_LBG | DBRI_MBE)) {
453 u_int32_t tmp;
454
455 if (x & DBRI_MRR)
456 aprint_debug("%s: multiple ack error on sbus\n",
457 sc->sc_dev.dv_xname);
458 if (x & DBRI_MLE)
459 aprint_debug("%s: multiple late error on sbus\n",
460 sc->sc_dev.dv_xname);
461 if (x & DBRI_LBG)
462 aprint_debug("%s: lost bus grant on sbus\n",
463 sc->sc_dev.dv_xname);
464 if (x & DBRI_MBE)
465 aprint_debug("%s: burst error on sbus\n",
466 sc->sc_dev.dv_xname);
467
468 /*
469 * Some of these errors disable the chip's circuitry.
470 * Re-enable the circuitry and keep on going.
471 */
472
473 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
474 tmp &= ~(DBRI_DISABLE_MASTER);
475 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
476 }
477
478 #if 0
479 if (!x & 1) /* XXX: DBRI_INTR_REQ */
480 return (1);
481 #endif
482
483 dbri_process_interrupt_buffer(sc);
484
485 return (1);
486 }
487
488 static int
489 dbri_init(struct dbri_softc *sc)
490 {
491 bus_space_tag_t iot = sc->sc_iot;
492 bus_space_handle_t ioh = sc->sc_ioh;
493 u_int32_t reg;
494 volatile u_int32_t *cmd;
495 bus_addr_t dmaaddr;
496 int n;
497
498 dbri_reset(sc);
499
500 cmd = dbri_command_lock(sc);
501
502 /* XXX: Initialize interrupt ring buffer */
503 sc->sc_dma->intr[0] = (u_int32_t)sc->sc_dmabase + dbri_dma_off(intr, 0);
504 sc->sc_irqp = 1;
505
506 /* Initialize pipes */
507 for (n = 0; n < DBRI_PIPE_MAX; n++)
508 sc->sc_pipe[n].desc = sc->sc_pipe[n].next = -1;
509
510 for (n = 1; n < DBRI_INT_BLOCKS; n++) {
511 sc->sc_dma->intr[n] = 0;
512 }
513
514 /* Disable all SBus bursts */
515 /* XXX 16 byte bursts cause errors, the rest works */
516 reg = bus_space_read_4(iot, ioh, DBRI_REG0);
517
518 /*reg &= ~(DBRI_BURST_4 | DBRI_BURST_8 | DBRI_BURST_16);*/
519 reg |= (DBRI_BURST_4 | DBRI_BURST_8);
520 bus_space_write_4(iot, ioh, DBRI_REG0, reg);
521
522 /* setup interrupt queue */
523 dmaaddr = (u_int32_t)sc->sc_dmabase + dbri_dma_off(intr, 0);
524 *(cmd++) = DBRI_CMD(DBRI_COMMAND_IIQ, 0, 0);
525 *(cmd++) = dmaaddr;
526
527 dbri_command_send(sc, cmd);
528 return (0);
529 }
530
531 static int
532 dbri_reset(struct dbri_softc *sc)
533 {
534 int bail = 0;
535
536 bus_space_tag_t iot = sc->sc_iot;
537 bus_space_handle_t ioh = sc->sc_ioh;
538
539 bus_space_write_4(iot, ioh, DBRI_REG0, DBRI_SOFT_RESET);
540 while ((bus_space_read_4(iot, ioh, DBRI_REG0) & DBRI_SOFT_RESET) &&
541 (bail < 100000)) {
542 bail++;
543 delay(10);
544 }
545 if (bail == 100000) aprint_error("%s: reset timed out\n",
546 sc->sc_dev.dv_xname);
547 return (0);
548 }
549
550 static volatile u_int32_t *
551 dbri_command_lock(struct dbri_softc *sc)
552 {
553
554 if (sc->sc_locked)
555 aprint_debug("%s: command buffer locked\n", sc->sc_dev.dv_xname);
556
557 sc->sc_locked++;
558
559 return (&sc->sc_dma->command[0]);
560 }
561
562 static void
563 dbri_command_send(struct dbri_softc *sc, volatile u_int32_t *cmd)
564 {
565 bus_space_handle_t ioh = sc->sc_ioh;
566 bus_space_tag_t iot = sc->sc_iot;
567 int maxloops = 1000000;
568 int x;
569
570 x = splaudio();
571
572 sc->sc_locked--;
573
574 if (sc->sc_locked != 0) {
575 aprint_error("%s: command buffer improperly locked\n",
576 sc->sc_dev.dv_xname);
577 } else if ((cmd - &sc->sc_dma->command[0]) >= DBRI_NUM_COMMANDS - 1) {
578 aprint_error("%s: command buffer overflow\n", sc->sc_dev.dv_xname);
579 } else {
580 *(cmd++) = DBRI_CMD(DBRI_COMMAND_PAUSE, 0, 0);
581 *(cmd++) = DBRI_CMD(DBRI_COMMAND_WAIT, 1, 0);
582 sc->sc_waitseen = 0;
583 bus_space_write_4(iot, ioh, DBRI_REG8, sc->sc_dmabase);
584 while ((--maxloops) > 0 &&
585 (bus_space_read_4(iot, ioh, DBRI_REG0)
586 & DBRI_COMMAND_VALID)) {
587 bus_space_barrier(iot, ioh, DBRI_REG0, 4,
588 BUS_SPACE_BARRIER_READ);
589 delay(1000);
590 }
591
592 if (maxloops == 0) {
593 aprint_error("%s: chip never completed command buffer\n",
594 sc->sc_dev.dv_xname);
595 } else {
596
597 DPRINTF("%s: command completed\n",
598 sc->sc_dev.dv_xname);
599
600 while ((--maxloops) > 0 && (!sc->sc_waitseen))
601 dbri_process_interrupt_buffer(sc);
602 if (maxloops == 0) {
603 aprint_error("%s: chip never acked WAIT\n",
604 sc->sc_dev.dv_xname);
605 }
606 }
607 }
608
609 splx(x);
610
611 return;
612 }
613
614 static void
615 dbri_process_interrupt_buffer(struct dbri_softc *sc)
616 {
617 int32_t i;
618
619 while ((i = sc->sc_dma->intr[sc->sc_irqp]) != 0) {
620 sc->sc_dma->intr[sc->sc_irqp] = 0;
621 sc->sc_irqp++;
622
623 if (sc->sc_irqp == DBRI_INT_BLOCKS)
624 sc->sc_irqp = 1;
625 else if ((sc->sc_irqp & (DBRI_INT_BLOCKS - 1)) == 0)
626 sc->sc_irqp++;
627
628 dbri_process_interrupt(sc, i);
629 }
630
631 return;
632 }
633
634 static void
635 dbri_process_interrupt(struct dbri_softc *sc, int32_t i)
636 {
637 #if 0
638 const int liu_states[] = { 1, 0, 8, 3, 4, 5, 6, 7 };
639 #endif
640 int val = DBRI_INTR_GETVAL(i);
641 int channel = DBRI_INTR_GETCHAN(i);
642 int command = DBRI_INTR_GETCMD(i);
643 int code = DBRI_INTR_GETCODE(i);
644 #if 0
645 int rval = DBRI_INTR_GETRVAL(i);
646 #endif
647 if (channel == DBRI_INTR_CMD && command == DBRI_COMMAND_WAIT)
648 sc->sc_waitseen++;
649
650 switch (code) {
651 case DBRI_INTR_XCMP: /* transmission complete */
652 {
653 int td;
654 struct dbri_desc *dd;
655
656 td = sc->sc_pipe[channel].desc;
657 dd = &sc->sc_desc[td];
658
659 if (dd->callback != NULL)
660 dd->callback(dd->callback_args);
661 break;
662 }
663 case DBRI_INTR_FXDT: /* fixed data change */
664 DPRINTF("dbri_intr: Fixed data change (%d: %x)\n", channel,
665 val);
666
667 if (sc->sc_pipe[channel].sdp & DBRI_SDP_MSB)
668 val = reverse_bytes(val, sc->sc_pipe[channel].length);
669 if (sc->sc_pipe[channel].prec)
670 *(sc->sc_pipe[channel].prec) = val;
671 DPRINTF("%s: wakeup %p\n", sc->sc_dev.dv_xname, sc);
672 #if 0
673 wakeup(sc);
674 #endif
675 break;
676 case DBRI_INTR_SBRI:
677 DPRINTF("dbri_intr: SBRI\n");
678 break;
679 case DBRI_INTR_BRDY:
680 {
681 /* XXX no input (yet) */
682 #if 0
683 int rd = sc->sc_pipe[channel].desc;
684 u_int32_t status;
685
686 DPRINTF("dbri_intr: BRDY\n");
687 if (rd < 0 || rd >= DBRI_NUM_DESCRIPTORS) {
688 printf("%s: invalid rd on pipe\n", sc->sc_dev.dv_xname);
689 break;
690 }
691
692 sc->sc_desc[rd].busy = 0;
693 sc->sc_pipe[channel].desc = sc->sc_desc[rd].next;
694 status = sc->sc_dma->desc[rd].word1;
695 #endif
696 /* XXX: callback ??? */
697
698 break;
699 }
700 case DBRI_INTR_UNDR:
701 {
702 volatile u_int32_t *cmd;
703 int td = sc->sc_pipe[channel].desc;
704
705 DPRINTF("%s: DBRI_INTR_UNDR\n", sc->sc_dev.dv_xname);
706
707 sc->sc_dma->desc[td].status = 0;
708
709 cmd = dbri_command_lock(sc);
710 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0,
711 sc->sc_pipe[channel].sdp |
712 DBRI_SDP_VALID_POINTER |
713 DBRI_SDP_CLEAR |
714 DBRI_SDP_2SAME);
715 *(cmd++) = sc->sc_dmabase + dbri_dma_off(desc, td);
716 dbri_command_send(sc, cmd);
717 break;
718 }
719 case DBRI_INTR_CMDI:
720 break;
721 default:
722
723 DPRINTF("%s: unknown interrupt code %d\n",
724 sc->sc_dev.dv_xname, code);
725 break;
726 }
727
728 return;
729 }
730
731 /*
732 * mmcodec stuff
733 */
734
735 static int
736 mmcodec_init(struct dbri_softc *sc)
737 {
738 bus_space_handle_t ioh = sc->sc_ioh;
739 bus_space_tag_t iot = sc->sc_iot;
740 u_int32_t reg2;
741 int bail;
742
743 reg2 = bus_space_read_4(iot, ioh, DBRI_REG2);
744 DPRINTF("mmcodec_init: PIO reads %x\n", reg2);
745
746 if (reg2 & DBRI_PIO2) {
747 aprint_normal("%s: onboard CS4215 detected\n",
748 sc->sc_dev.dv_xname);
749 sc->sc_mm.onboard = 1;
750 }
751
752 if (reg2 & DBRI_PIO0) {
753 aprint_normal("%s: speakerbox detected\n",
754 sc->sc_dev.dv_xname);
755 sc->sc_mm.onboard = 0;
756 }
757
758 if ((reg2 & DBRI_PIO2) && (reg2 & DBRI_PIO0)) {
759 aprint_normal("%s: using speakerbox\n",
760 sc->sc_dev.dv_xname);
761 bus_space_write_4(iot, ioh, DBRI_REG2, DBRI_PIO2_ENABLE);
762 sc->sc_mm.onboard = 0;
763 }
764
765 if (!(reg2 & (DBRI_PIO0|DBRI_PIO2))) {
766 aprint_normal("%s: no mmcodec found\n", sc->sc_dev.dv_xname);
767 return -1;
768 }
769
770 sc->sc_version = 0xff;
771
772 mmcodec_pipe_init(sc);
773 mmcodec_default(sc);
774
775 sc->sc_mm.offset = sc->sc_mm.onboard ? 0 : 8;
776
777 /*
778 * mmcodec_setcontrol() sometimes fails right after powerup
779 * so we just try again until we either get a useful response or run
780 * out of time
781 */
782 bail = 0;
783 while (mmcodec_setcontrol(sc) == -1 || sc->sc_version == 0xff) {
784
785 bail++;
786 if (bail > 100) {
787 DPRINTF("%s: cs4215 probe failed at offset %d\n",
788 sc->sc_dev.dv_xname, sc->sc_mm.offset);
789 return (-1);
790 }
791 delay(10000);
792 }
793
794 aprint_normal("%s: cs4215 ver %d found at offset %d\n",
795 sc->sc_dev.dv_xname, sc->sc_version & 0xf, sc->sc_mm.offset);
796
797 /* set some sane defaults for mmcodec_init_data */
798 sc->sc_params.channels = 2;
799 sc->sc_params.precision = 16;
800
801 mmcodec_init_data(sc);
802
803 sc->sc_open = 0;
804
805 return (0);
806 }
807
808 static void
809 mmcodec_init_data(struct dbri_softc *sc)
810 {
811 bus_space_tag_t iot = sc->sc_iot;
812 bus_space_handle_t ioh = sc->sc_ioh;
813 u_int32_t tmp;
814 int data_width;
815
816 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
817 tmp &= ~(DBRI_CHI_ACTIVATE); /* disable CHI */
818 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
819
820 /* switch CS4215 to data mode - set PIO3 to 1 */
821 tmp = DBRI_PIO_ENABLE_ALL | DBRI_PIO1 | DBRI_PIO3;
822
823 /* XXX */
824 tmp |= (sc->sc_mm.onboard ? DBRI_PIO0 : DBRI_PIO2);
825
826 bus_space_write_4(iot, ioh, DBRI_REG2, tmp);
827 chi_reset(sc, CHIslave, 128);
828
829 data_width = sc->sc_params.channels * sc->sc_params.precision;
830 pipe_ts_link(sc, 20, PIPEoutput, 16, 32, sc->sc_mm.offset + 32);
831 pipe_ts_link(sc, 4, PIPEoutput, 16, data_width, sc->sc_mm.offset);
832 pipe_ts_link(sc, 6, PIPEinput, 16, data_width, sc->sc_mm.offset);
833 pipe_ts_link(sc, 21, PIPEinput, 16, 16, sc->sc_mm.offset + 40);
834
835 mmcodec_setgain(sc, 0);
836
837 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
838 tmp |= DBRI_CHI_ACTIVATE;
839 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
840
841 return;
842 }
843
844 static void
845 mmcodec_pipe_init(struct dbri_softc *sc)
846 {
847
848 pipe_setup(sc, 4, DBRI_SDP_MEM | DBRI_SDP_TO_SER | DBRI_SDP_MSB);
849 pipe_setup(sc, 20, DBRI_SDP_FIXED | DBRI_SDP_TO_SER | DBRI_SDP_MSB);
850 pipe_setup(sc, 6, DBRI_SDP_MEM | DBRI_SDP_FROM_SER | DBRI_SDP_MSB);
851 pipe_setup(sc, 21, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB);
852
853 pipe_setup(sc, 17, DBRI_SDP_FIXED | DBRI_SDP_TO_SER | DBRI_SDP_MSB);
854 pipe_setup(sc, 18, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB);
855 pipe_setup(sc, 19, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB);
856
857 sc->sc_mm.status = 0;
858
859 pipe_receive_fixed(sc, 18, &sc->sc_mm.status);
860 pipe_receive_fixed(sc, 19, &sc->sc_mm.version);
861
862 return;
863 }
864
865 static void
866 mmcodec_default(struct dbri_softc *sc)
867 {
868 struct cs4215_state *mm = &sc->sc_mm;
869
870 /*
871 * no action, memory resetting only
872 *
873 * data time slots 5-8
874 * speaker, line and headphone enable. set gain to half.
875 * input is mic
876 */
877 mm->d.bdata[0] = sc->sc_latt = 0x20 | CS4215_HE | CS4215_LE;
878 mm->d.bdata[1] = sc->sc_ratt = 0x20 | CS4215_SE;
879 mm->d.bdata[2] = CS4215_LG(0x08) | CS4215_IS | CS4215_PIO0 | CS4215_PIO1;
880 mm->d.bdata[3] = CS4215_RG(0x08) | CS4215_MA(0x0f);
881
882 /*
883 * control time slots 1-4
884 *
885 * 0: default I/O voltage scale
886 * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled
887 * 2: serial enable, CHI master, 128 bits per frame, clock 1
888 * 3: tests disabled
889 */
890 mm->c.bcontrol[0] = CS4215_RSRVD_1 | CS4215_MLB;
891 mm->c.bcontrol[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval;
892 mm->c.bcontrol[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal;
893 mm->c.bcontrol[3] = 0;
894
895 return;
896 }
897
898 static void
899 mmcodec_setgain(struct dbri_softc *sc, int mute)
900 {
901 if (mute) {
902 /* disable all outputs, max. attenuation */
903 sc->sc_mm.d.bdata[0] = sc->sc_latt | 63;
904 sc->sc_mm.d.bdata[1] = sc->sc_ratt | 63;
905 } else {
906 /*
907 * We should be setting the proper output here.. for now,
908 * use the speaker. Possible outputs:
909 * Headphones:
910 * data[0] |= CS4215_HE;
911 * Line out:
912 * data[0] |= CS4215_LE;
913 * Speaker:
914 * data[1] |= CS4215_SE;
915 */
916 sc->sc_mm.d.bdata[0] = sc->sc_latt;
917 sc->sc_mm.d.bdata[1] = sc->sc_ratt;
918 }
919
920 if (sc->sc_powerstate == 0)
921 return;
922 pipe_transmit_fixed(sc, 20, sc->sc_mm.d.ldata);
923
924 /* give the chip some time to execure the command */
925 delay(250);
926
927 return;
928 }
929
930 static int
931 mmcodec_setcontrol(struct dbri_softc *sc)
932 {
933 bus_space_tag_t iot = sc->sc_iot;
934 bus_space_handle_t ioh = sc->sc_ioh;
935 u_int32_t val;
936 u_int32_t tmp;
937 #if 1
938 int i;
939 #endif
940
941 /*
942 * Temporarily mute outputs and wait 125 us to make sure that it
943 * happens. This avoids clicking noises.
944 */
945 mmcodec_setgain(sc, 1);
946 delay(125);
947
948 /* enable control mode */
949 val = DBRI_PIO_ENABLE_ALL | DBRI_PIO1; /* was PIO1 */
950
951 /* XXX */
952 val |= (sc->sc_mm.onboard ? DBRI_PIO0 : DBRI_PIO2);
953
954 bus_space_write_4(iot, ioh, DBRI_REG2, val);
955
956 delay(34);
957
958 /*
959 * in control mode, the cs4215 is the slave device, so the
960 * DBRI must act as the CHI master.
961 *
962 * in data mode, the cs4215 must be the CHI master to insure
963 * that the data stream is in sync with its codec
964 */
965 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
966 tmp &= ~DBRI_COMMAND_CHI;
967 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
968
969 chi_reset(sc, CHImaster, 128);
970
971 /* control mode */
972 pipe_ts_link(sc, 17, PIPEoutput, 16, 32, sc->sc_mm.offset);
973 pipe_ts_link(sc, 18, PIPEinput, 16, 8, sc->sc_mm.offset);
974 pipe_ts_link(sc, 19, PIPEinput, 16, 8, sc->sc_mm.offset + 48);
975
976 /* wait for the chip to echo back CLB as zero */
977 sc->sc_mm.c.bcontrol[0] &= ~CS4215_CLB;
978 pipe_transmit_fixed(sc, 17, sc->sc_mm.c.lcontrol);
979
980 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
981 tmp |= DBRI_CHI_ACTIVATE;
982 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
983
984 #if 1
985 i = 1024;
986 while (((sc->sc_mm.status & 0xe4) != 0x20) && --i) {
987 delay(125);
988 }
989
990 if (i == 0) {
991 DPRINTF("%s: cs4215 didn't respond to CLB (0x%02x)\n",
992 sc->sc_dev.dv_xname, sc->sc_mm.status);
993 return (-1);
994 }
995 #else
996 while ((sc->sc_mm.status & 0xe4) != 0x20) {
997 DPRINTF("%s: tsleep %p\n", sc->sc_dev.dv_xname, sc);
998 tsleep(sc, PCATCH | PZERO, "dbrifxdt", 0);
999 }
1000 #endif
1001
1002 /* copy the version information before it becomes unreadable again */
1003 sc->sc_version = sc->sc_mm.version;
1004
1005 /* terminate cs4215 control mode */
1006 sc->sc_mm.c.bcontrol[0] |= CS4215_CLB;
1007 pipe_transmit_fixed(sc, 17, sc->sc_mm.c.lcontrol);
1008
1009 /* two frames of control info @ 8kHz frame rate = 250us delay */
1010 delay(250);
1011
1012 mmcodec_setgain(sc, 0);
1013
1014 return (0);
1015
1016 }
1017
1018 /*
1019 * CHI combo
1020 */
1021 static void
1022 chi_reset(struct dbri_softc *sc, enum ms ms, int bpf)
1023 {
1024 volatile u_int32_t *cmd;
1025 int val;
1026 int clockrate, divisor;
1027
1028 cmd = dbri_command_lock(sc);
1029
1030 /* set CHI anchor: pipe 16 */
1031 val = DBRI_DTS_VI | DBRI_DTS_INS | DBRI_DTS_PRVIN(16) | DBRI_PIPE(16);
1032 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val);
1033 *(cmd++) = DBRI_TS_ANCHOR | DBRI_TS_NEXT(16);
1034 *(cmd++) = 0;
1035
1036 val = DBRI_DTS_VO | DBRI_DTS_INS | DBRI_DTS_PRVOUT(16) | DBRI_PIPE(16);
1037 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val);
1038 *(cmd++) = 0;
1039 *(cmd++) = DBRI_TS_ANCHOR | DBRI_TS_NEXT(16);
1040
1041 sc->sc_pipe[16].sdp = 1;
1042 sc->sc_pipe[16].next = 16;
1043 sc->sc_chi_pipe_in = 16;
1044 sc->sc_chi_pipe_out = 16;
1045
1046 switch (ms) {
1047 case CHIslave:
1048 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CHI, 0, DBRI_CHI_CHICM(0));
1049 break;
1050 case CHImaster:
1051 clockrate = bpf * 8;
1052 divisor = 12288 / clockrate;
1053
1054 if (divisor > 255 || divisor * clockrate != 12288)
1055 aprint_error("%s: illegal bits-per-frame %d\n",
1056 sc->sc_dev.dv_xname, bpf);
1057
1058 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CHI, 0,
1059 DBRI_CHI_CHICM(divisor) | DBRI_CHI_FD | DBRI_CHI_BPF(bpf));
1060 break;
1061 default:
1062 aprint_error("%s: unknown value for ms!\n", sc->sc_dev.dv_xname);
1063 break;
1064 }
1065
1066 sc->sc_chi_bpf = bpf;
1067
1068 /* CHI data mode */
1069 *(cmd++) = DBRI_CMD(DBRI_COMMAND_PAUSE, 0, 0);
1070 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CDM, 0,
1071 DBRI_CDM_XCE | DBRI_CDM_XEN | DBRI_CDM_REN);
1072
1073 dbri_command_send(sc, cmd);
1074
1075 return;
1076 }
1077
1078 /*
1079 * pipe stuff
1080 */
1081 static void
1082 pipe_setup(struct dbri_softc *sc, int pipe, int sdp)
1083 {
1084 DPRINTF("pipe setup: %d\n", pipe);
1085 if (pipe < 0 || pipe >= DBRI_PIPE_MAX) {
1086 aprint_error("%s: illegal pipe number %d\n", sc->sc_dev.dv_xname,
1087 pipe);
1088 return;
1089 }
1090
1091 if ((sdp & 0xf800) != sdp)
1092 aprint_error("%s: strange SDP value %d\n", sc->sc_dev.dv_xname, sdp);
1093
1094 if (DBRI_SDP_MODE(sdp) == DBRI_SDP_FIXED &&
1095 !(sdp & DBRI_SDP_TO_SER))
1096 sdp |= DBRI_SDP_CHANGE;
1097
1098 sdp |= DBRI_PIPE(pipe);
1099
1100 sc->sc_pipe[pipe].sdp = sdp;
1101 sc->sc_pipe[pipe].desc = -1;
1102
1103 pipe_reset(sc, pipe);
1104
1105 return;
1106 }
1107
1108 static void
1109 pipe_reset(struct dbri_softc *sc, int pipe)
1110 {
1111 struct dbri_desc *dd;
1112 int sdp;
1113 int desc;
1114 volatile u_int32_t *cmd;
1115
1116 if (pipe < 0 || pipe >= DBRI_PIPE_MAX) {
1117 aprint_error("%s: illegal pipe number %d\n", sc->sc_dev.dv_xname,
1118 pipe);
1119 return;
1120 }
1121
1122 sdp = sc->sc_pipe[pipe].sdp;
1123 if (sdp == 0) {
1124 aprint_error("%s: can not reset uninitialized pipe %d\n",
1125 sc->sc_dev.dv_xname, pipe);
1126 return;
1127 }
1128
1129 cmd = dbri_command_lock(sc);
1130 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0,
1131 sdp | DBRI_SDP_CLEAR | DBRI_SDP_VALID_POINTER);
1132 *(cmd++) = 0;
1133 dbri_command_send(sc, cmd);
1134
1135 desc = sc->sc_pipe[pipe].desc;
1136
1137 dd = &sc->sc_desc[desc];
1138
1139 dd->busy = 0;
1140
1141 #if 0
1142 if (dd->callback)
1143 (*dd->callback)(dd->callback_args);
1144 #endif
1145
1146 sc->sc_pipe[pipe].desc = -1;
1147
1148 return;
1149 }
1150
1151 static void
1152 pipe_receive_fixed(struct dbri_softc *sc, int pipe, volatile u_int32_t *prec)
1153 {
1154
1155 if (pipe < DBRI_PIPE_MAX / 2 || pipe >= DBRI_PIPE_MAX) {
1156 aprint_error("%s: illegal pipe number %d\n",
1157 sc->sc_dev.dv_xname, pipe);
1158 return;
1159 }
1160
1161 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) != DBRI_SDP_FIXED) {
1162 aprint_error("%s: non-fixed pipe %d\n", sc->sc_dev.dv_xname,
1163 pipe);
1164 return;
1165 }
1166
1167 if (sc->sc_pipe[pipe].sdp & DBRI_SDP_TO_SER) {
1168 aprint_error("%s: can not receive on transmit pipe %d\b",
1169 sc->sc_dev.dv_xname, pipe);
1170 return;
1171 }
1172
1173 sc->sc_pipe[pipe].prec = prec;
1174
1175 return;
1176 }
1177
1178 static void
1179 pipe_transmit_fixed(struct dbri_softc *sc, int pipe, u_int32_t data)
1180 {
1181 volatile u_int32_t *cmd;
1182
1183 if (pipe < DBRI_PIPE_MAX / 2 || pipe >= DBRI_PIPE_MAX) {
1184 aprint_error("%s: illegal pipe number %d\n",
1185 sc->sc_dev.dv_xname, pipe);
1186 return;
1187 }
1188
1189 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) == 0) {
1190 aprint_error("%s: uninitialized pipe %d\n",
1191 sc->sc_dev.dv_xname, pipe);
1192 return;
1193 }
1194
1195 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) != DBRI_SDP_FIXED) {
1196 aprint_error("%s: non-fixed pipe %d\n", sc->sc_dev.dv_xname,
1197 pipe);
1198 return;
1199 }
1200
1201 if (!(sc->sc_pipe[pipe].sdp & DBRI_SDP_TO_SER)) {
1202 aprint_error("%s: called on receive pipe %d\n",
1203 sc->sc_dev.dv_xname, pipe);
1204 return;
1205 }
1206
1207 if (sc->sc_pipe[pipe].sdp & DBRI_SDP_MSB)
1208 data = reverse_bytes(data, sc->sc_pipe[pipe].length);
1209
1210 cmd = dbri_command_lock(sc);
1211 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SSP, 0, pipe);
1212 *(cmd++) = data;
1213
1214 dbri_command_send(sc, cmd);
1215
1216 return;
1217 }
1218
1219 static void
1220 setup_ring(struct dbri_softc *sc, int pipe, int which, int num, int blksz,
1221 void (*callback)(void *), void *callback_args)
1222 {
1223 volatile u_int32_t *cmd;
1224 int x, i;
1225 int td;
1226 int td_first, td_last;
1227 bus_addr_t dmabuf, dmabase;
1228 struct dbri_desc *dd = &sc->sc_desc[which];
1229
1230 td = 0;
1231 td_first = td_last = -1;
1232
1233 if (pipe < 0 || pipe >= DBRI_PIPE_MAX / 2) {
1234 aprint_error("%s: illegal pipe number %d\n",
1235 sc->sc_dev.dv_xname, pipe);
1236 return;
1237 }
1238
1239 if (sc->sc_pipe[pipe].sdp == 0) {
1240 aprint_error("%s: uninitialized pipe %d\n",
1241 sc->sc_dev.dv_xname, pipe);
1242 return;
1243 }
1244
1245 if (!(sc->sc_pipe[pipe].sdp & DBRI_SDP_TO_SER)) {
1246 aprint_error("%s: called on receive pipe %d\n",
1247 sc->sc_dev.dv_xname, pipe);
1248 return;
1249 }
1250
1251
1252 dmabuf = dd->dmabase;
1253 dmabase = sc->sc_dmabase;
1254 td = 0;
1255
1256 for (i = 0; i < (num-1); i++) {
1257
1258 sc->sc_dma->desc[i].flags = TX_BCNT(blksz)
1259 | TX_EOF | TX_BINT;
1260 sc->sc_dma->desc[i].ba = dmabuf;
1261 sc->sc_dma->desc[i].nda = dmabase + dbri_dma_off(desc, i + 1);
1262 sc->sc_dma->desc[i].status = 0;
1263
1264 td_last = td;
1265 dmabuf += blksz;
1266 }
1267
1268 sc->sc_dma->desc[i].flags = TX_BCNT(blksz) | TX_EOF | TX_BINT;
1269 sc->sc_dma->desc[i].ba = dmabuf;
1270 sc->sc_dma->desc[i].nda = dmabase + dbri_dma_off(desc, 0);
1271 sc->sc_dma->desc[i].status = 0;
1272
1273 dd->callback = callback;
1274 dd->callback_args = callback_args;
1275
1276 x = splaudio();
1277
1278 /* the pipe shouldn't be active */
1279 if (pipe_active(sc, pipe)) {
1280 aprint_error("pipe active (CDP)\n");
1281 /* pipe is already active */
1282 #if 0
1283 td_last = sc->sc_pipe[pipe].desc;
1284 while (sc->sc_desc[td_last].next != -1)
1285 td_last = sc->sc_desc[td_last].next;
1286
1287 sc->sc_desc[td_last].next = td_first;
1288 sc->sc_dma->desc[td_last].nda =
1289 sc->sc_dmabase + dbri_dma_off(desc, td_first);
1290
1291 cmd = dbri_command_lock(sc);
1292 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CDP, 0, pipe);
1293 dbri_command_send(sc, cmd);
1294 #endif
1295 } else {
1296 /*
1297 * pipe isn't active - issue an SDP command to start our
1298 * chain of TDs running
1299 */
1300 sc->sc_pipe[pipe].desc = which;
1301 cmd = dbri_command_lock(sc);
1302 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0,
1303 sc->sc_pipe[pipe].sdp |
1304 DBRI_SDP_VALID_POINTER |
1305 DBRI_SDP_EVERY |
1306 DBRI_SDP_CLEAR);
1307 *(cmd++) = sc->sc_dmabase + dbri_dma_off(desc, 0);
1308 dbri_command_send(sc, cmd);
1309 }
1310
1311 splx(x);
1312
1313 return;
1314 }
1315
1316 static void
1317 pipe_ts_link(struct dbri_softc *sc, int pipe, enum io dir, int basepipe,
1318 int len, int cycle)
1319 {
1320 volatile u_int32_t *cmd;
1321 int prevpipe, nextpipe;
1322 int val;
1323
1324 if (pipe < 0 || pipe >= DBRI_PIPE_MAX ||
1325 basepipe < 0 || basepipe >= DBRI_PIPE_MAX) {
1326 aprint_error("%s: illegal pipe numbers (%d, %d)\n",
1327 sc->sc_dev.dv_xname, pipe, basepipe);
1328 return;
1329 }
1330
1331 if (sc->sc_pipe[pipe].sdp == 0 || sc->sc_pipe[basepipe].sdp == 0) {
1332 aprint_error("%s: uninitialized pipe (%d, %d)\n",
1333 sc->sc_dev.dv_xname, pipe, basepipe);
1334 return;
1335 }
1336
1337 if (basepipe == 16 && dir == PIPEoutput && cycle == 0)
1338 cycle = sc->sc_chi_bpf;
1339
1340 if (basepipe == pipe)
1341 prevpipe = nextpipe = pipe;
1342 else {
1343 if (basepipe == 16) {
1344 if (dir == PIPEinput) {
1345 prevpipe = sc->sc_chi_pipe_in;
1346 } else {
1347 prevpipe = sc->sc_chi_pipe_out;
1348 }
1349 } else
1350 prevpipe = basepipe;
1351
1352 nextpipe = sc->sc_pipe[prevpipe].next;
1353
1354 while (sc->sc_pipe[nextpipe].cycle < cycle &&
1355 sc->sc_pipe[nextpipe].next != basepipe) {
1356 prevpipe = nextpipe;
1357 nextpipe = sc->sc_pipe[nextpipe].next;
1358 }
1359 }
1360
1361 if (prevpipe == 16) {
1362 if (dir == PIPEinput) {
1363 sc->sc_chi_pipe_in = pipe;
1364 } else {
1365 sc->sc_chi_pipe_out = pipe;
1366 }
1367 } else
1368 sc->sc_pipe[prevpipe].next = pipe;
1369
1370 sc->sc_pipe[pipe].next = nextpipe;
1371 sc->sc_pipe[pipe].cycle = cycle;
1372 sc->sc_pipe[pipe].length = len;
1373
1374 cmd = dbri_command_lock(sc);
1375
1376 switch (dir) {
1377 case PIPEinput:
1378 val = DBRI_DTS_VI | DBRI_DTS_INS | DBRI_DTS_PRVIN(prevpipe);
1379 val |= pipe;
1380 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val);
1381 *(cmd++) = DBRI_TS_LEN(len) | DBRI_TS_CYCLE(cycle) |
1382 DBRI_TS_NEXT(nextpipe);
1383 *(cmd++) = 0;
1384 break;
1385 case PIPEoutput:
1386 val = DBRI_DTS_VO | DBRI_DTS_INS | DBRI_DTS_PRVOUT(prevpipe);
1387 val |= pipe;
1388 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val);
1389 *(cmd++) = 0;
1390 *(cmd++) = DBRI_TS_LEN(len) | DBRI_TS_CYCLE(cycle) |
1391 DBRI_TS_NEXT(nextpipe);
1392 break;
1393 default:
1394 DPRINTF("%s: should not have happened!\n",
1395 sc->sc_dev.dv_xname);
1396 break;
1397 }
1398
1399 dbri_command_send(sc, cmd);
1400
1401 return;
1402 }
1403
1404 static int
1405 pipe_active(struct dbri_softc *sc, int pipe)
1406 {
1407
1408 return (sc->sc_pipe[pipe].desc != -1);
1409 }
1410
1411 /*
1412 * subroutines required to interface with audio(9)
1413 */
1414
1415 static int
1416 dbri_query_encoding(void *hdl, struct audio_encoding *ae)
1417 {
1418
1419 switch (ae->index) {
1420 case 0:
1421 strcpy(ae->name, AudioEulinear);
1422 ae->encoding = AUDIO_ENCODING_ULINEAR;
1423 ae->precision = 8;
1424 ae->flags = 0;
1425 break;
1426 case 1:
1427 strcpy(ae->name, AudioEmulaw);
1428 ae->encoding = AUDIO_ENCODING_ULAW;
1429 ae->precision = 8;
1430 ae->flags = 0;
1431 break;
1432 case 2:
1433 strcpy(ae->name, AudioEalaw);
1434 ae->encoding = AUDIO_ENCODING_ALAW;
1435 ae->precision = 8;
1436 ae->flags = 0;
1437 break;
1438 case 3:
1439 strcpy(ae->name, AudioEslinear);
1440 ae->encoding = AUDIO_ENCODING_SLINEAR;
1441 ae->precision = 8;
1442 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
1443 break;
1444 case 4:
1445 strcpy(ae->name, AudioEslinear_le);
1446 ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
1447 ae->precision = 16;
1448 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
1449 break;
1450 case 5:
1451 strcpy(ae->name, AudioEulinear_le);
1452 ae->encoding = AUDIO_ENCODING_ULINEAR_LE;
1453 ae->precision = 16;
1454 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
1455 break;
1456 case 6:
1457 strcpy(ae->name, AudioEslinear_be);
1458 ae->encoding = AUDIO_ENCODING_SLINEAR_BE;
1459 ae->precision = 16;
1460 ae->flags = 0;
1461 break;
1462 case 7:
1463 strcpy(ae->name, AudioEulinear_be);
1464 ae->encoding = AUDIO_ENCODING_ULINEAR_BE;
1465 ae->precision = 16;
1466 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
1467 break;
1468 case 8:
1469 strcpy(ae->name, AudioEslinear);
1470 ae->encoding = AUDIO_ENCODING_SLINEAR;
1471 ae->precision = 16;
1472 ae->flags = 0;
1473 break;
1474 default:
1475 return (EINVAL);
1476 }
1477
1478 return (0);
1479 }
1480
1481 /*
1482 * XXX: recording isn't supported - jmcneill
1483 */
1484 static int
1485 dbri_set_params(void *hdl, int setmode, int usemode,
1486 struct audio_params *play, struct audio_params *rec,
1487 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
1488 {
1489 struct dbri_softc *sc = hdl;
1490 int rate;
1491 audio_params_t *p = NULL;
1492 stream_filter_list_t *fil;
1493 int mode;
1494
1495 /*
1496 * This device only has one clock, so make the sample rates match.
1497 */
1498 if (play->sample_rate != rec->sample_rate &&
1499 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
1500 if (setmode == AUMODE_PLAY) {
1501 rec->sample_rate = play->sample_rate;
1502 setmode |= AUMODE_RECORD;
1503 } else if (setmode == AUMODE_RECORD) {
1504 play->sample_rate = rec->sample_rate;
1505 setmode |= AUMODE_PLAY;
1506 } else
1507 return EINVAL;
1508 }
1509
1510 for (mode = AUMODE_RECORD; mode != -1;
1511 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
1512 if ((setmode & mode) == 0)
1513 continue;
1514
1515 p = mode == AUMODE_PLAY ? play : rec;
1516 if (p->sample_rate < 4000 || p->sample_rate > 50000) {
1517 DPRINTF("dbri_set_params: invalid rate %d\n",
1518 p->sample_rate);
1519 return EINVAL;
1520 }
1521
1522 fil = mode == AUMODE_PLAY ? pfil : rfil;
1523 DPRINTF("enc: %d rate: %d prec: %d chan: %d\n", p->encoding,
1524 p->sample_rate, p->precision, p->channels);
1525 if (auconv_set_converter(dbri_formats, DBRI_NFORMATS,
1526 mode, p, true, fil) < 0) {
1527 DPRINTF("dbri_set_params: auconv_set_converter failed\n");
1528 return EINVAL;
1529 }
1530 if (fil->req_size > 0)
1531 p = &fil->filters[0].param;
1532 }
1533
1534 if (p == NULL) {
1535 DPRINTF("dbri_set_params: no parameters to set\n");
1536 return 0;
1537 }
1538
1539 DPRINTF("enc: %d rate: %d prec: %d chan: %d\n", p->encoding,
1540 p->sample_rate, p->precision, p->channels);
1541
1542 for (rate = 0; CS4215_FREQ[rate].freq; rate++)
1543 if (CS4215_FREQ[rate].freq == p->sample_rate)
1544 break;
1545
1546 if (CS4215_FREQ[rate].freq == 0)
1547 return (EINVAL);
1548
1549 /* set frequency */
1550 sc->sc_mm.c.bcontrol[1] &= ~0x38;
1551 sc->sc_mm.c.bcontrol[1] |= CS4215_FREQ[rate].csval;
1552 sc->sc_mm.c.bcontrol[2] &= ~0x70;
1553 sc->sc_mm.c.bcontrol[2] |= CS4215_FREQ[rate].xtal;
1554
1555 switch (p->encoding) {
1556 case AUDIO_ENCODING_ULAW:
1557 sc->sc_mm.c.bcontrol[1] &= ~3;
1558 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_ULAW;
1559 break;
1560 case AUDIO_ENCODING_ALAW:
1561 sc->sc_mm.c.bcontrol[1] &= ~3;
1562 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_ALAW;
1563 break;
1564 case AUDIO_ENCODING_ULINEAR:
1565 sc->sc_mm.c.bcontrol[1] &= ~3;
1566 if (p->precision == 8) {
1567 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR8;
1568 } else {
1569 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR16;
1570 }
1571 break;
1572 case AUDIO_ENCODING_SLINEAR_BE:
1573 case AUDIO_ENCODING_SLINEAR:
1574 sc->sc_mm.c.bcontrol[1] &= ~3;
1575 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR16;
1576 break;
1577 }
1578
1579 switch (p->channels) {
1580 case 1:
1581 sc->sc_mm.c.bcontrol[1] &= ~CS4215_DFR_STEREO;
1582 break;
1583 case 2:
1584 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_STEREO;
1585 break;
1586 }
1587
1588 return (0);
1589 }
1590
1591 static int
1592 dbri_round_blocksize(void *hdl, int bs, int mode,
1593 const audio_params_t *param)
1594 {
1595
1596 /* DBRI DMA segment size, rounded town to 32bit alignment */
1597 return 0x1ffc;
1598 }
1599
1600 static int
1601 dbri_halt_output(void *hdl)
1602 {
1603 struct dbri_softc *sc = hdl;
1604
1605 pipe_reset(sc, 4);
1606
1607 return (0);
1608 }
1609
1610 static int
1611 dbri_getdev(void *hdl, struct audio_device *ret)
1612 {
1613
1614 *ret = dbri_device;
1615 return (0);
1616 }
1617
1618 static int
1619 dbri_set_port(void *hdl, mixer_ctrl_t *mc)
1620 {
1621 struct dbri_softc *sc = hdl;
1622 int latt = sc->sc_latt, ratt = sc->sc_ratt;
1623
1624 switch (mc->dev) {
1625 case DBRI_VOL_OUTPUT: /* master volume */
1626 latt = (latt & 0xc0) | (63 -
1627 min(mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] >> 2, 63));
1628 ratt = (ratt & 0xc0) | (63 -
1629 min(mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] >> 2, 63));
1630 break;
1631 case DBRI_ENABLE_MONO: /* built-in speaker */
1632 if (mc->un.ord == 1) {
1633 ratt |= CS4215_SE;
1634 } else
1635 ratt &= ~CS4215_SE;
1636 break;
1637 case DBRI_ENABLE_HEADPHONE: /* headphones output */
1638 if (mc->un.ord == 1) {
1639 latt |= CS4215_HE;
1640 } else
1641 latt &= ~CS4215_HE;
1642 break;
1643 case DBRI_ENABLE_LINE: /* line out */
1644 if (mc->un.ord == 1) {
1645 latt |= CS4215_LE;
1646 } else
1647 latt &= ~CS4215_LE;
1648 break;
1649 }
1650
1651 sc->sc_latt = latt;
1652 sc->sc_ratt = ratt;
1653
1654 mmcodec_setgain(sc, 0);
1655
1656 return (0);
1657 }
1658
1659 static int
1660 dbri_get_port(void *hdl, mixer_ctrl_t *mc)
1661 {
1662 struct dbri_softc *sc = hdl;
1663
1664 switch (mc->dev) {
1665 case DBRI_VOL_OUTPUT: /* master volume */
1666 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1667 (63 - (sc->sc_latt & 0x3f)) << 2;
1668 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1669 (63 - (sc->sc_ratt & 0x3f)) << 2;
1670 return (0);
1671 case DBRI_ENABLE_MONO: /* built-in speaker */
1672 mc->un.ord = (sc->sc_ratt & CS4215_SE) ? 1 : 0;
1673 return 0;
1674 case DBRI_ENABLE_HEADPHONE: /* headphones output */
1675 mc->un.ord = (sc->sc_latt & CS4215_HE) ? 1 : 0;
1676 return 0;
1677 case DBRI_ENABLE_LINE: /* line out */
1678 mc->un.ord = (sc->sc_latt & CS4215_LE) ? 1 : 0;
1679 return 0;
1680 }
1681 return (EINVAL);
1682 }
1683
1684 static int
1685 dbri_query_devinfo(void *hdl, mixer_devinfo_t *di)
1686 {
1687
1688 switch (di->index) {
1689 case DBRI_MONITOR_CLASS:
1690 di->mixer_class = DBRI_MONITOR_CLASS;
1691 strcpy(di->label.name, AudioCmonitor);
1692 di->type = AUDIO_MIXER_CLASS;
1693 di->next = di->prev = AUDIO_MIXER_LAST;
1694 return 0;
1695 case DBRI_VOL_OUTPUT: /* master volume */
1696 di->mixer_class = DBRI_MONITOR_CLASS;
1697 di->next = di->prev = AUDIO_MIXER_LAST;
1698 strcpy(di->label.name, AudioNmaster);
1699 di->type = AUDIO_MIXER_VALUE;
1700 di->un.v.num_channels = 2;
1701 strcpy(di->un.v.units.name, AudioNvolume);
1702 return (0);
1703 case DBRI_ENABLE_MONO: /* built-in speaker */
1704 di->mixer_class = DBRI_MONITOR_CLASS;
1705 di->next = di->prev = AUDIO_MIXER_LAST;
1706 strcpy(di->label.name, AudioNmono);
1707 di->type = AUDIO_MIXER_ENUM;
1708 di->un.e.num_mem = 2;
1709 strcpy(di->un.e.member[0].label.name, AudioNoff);
1710 di->un.e.member[0].ord = 0;
1711 strcpy(di->un.e.member[1].label.name, AudioNon);
1712 di->un.e.member[1].ord = 1;
1713 return (0);
1714 case DBRI_ENABLE_HEADPHONE: /* headphones output */
1715 di->mixer_class = DBRI_MONITOR_CLASS;
1716 di->next = di->prev = AUDIO_MIXER_LAST;
1717 strcpy(di->label.name, AudioNheadphone);
1718 di->type = AUDIO_MIXER_ENUM;
1719 di->un.e.num_mem = 2;
1720 strcpy(di->un.e.member[0].label.name, AudioNoff);
1721 di->un.e.member[0].ord = 0;
1722 strcpy(di->un.e.member[1].label.name, AudioNon);
1723 di->un.e.member[1].ord = 1;
1724 return (0);
1725 case DBRI_ENABLE_LINE: /* line out */
1726 di->mixer_class = DBRI_MONITOR_CLASS;
1727 di->next = di->prev = AUDIO_MIXER_LAST;
1728 strcpy(di->label.name, AudioNline);
1729 di->type = AUDIO_MIXER_ENUM;
1730 di->un.e.num_mem = 2;
1731 strcpy(di->un.e.member[0].label.name, AudioNoff);
1732 di->un.e.member[0].ord = 0;
1733 strcpy(di->un.e.member[1].label.name, AudioNon);
1734 di->un.e.member[1].ord = 1;
1735 return (0);
1736 }
1737
1738 return (ENXIO);
1739 }
1740
1741 static size_t
1742 dbri_round_buffersize(void *hdl, int dir, size_t bufsize)
1743 {
1744 #ifdef DBRI_BIG_BUFFER
1745 return 16*0x1ffc; /* use ~128KB buffer */
1746 #else
1747 return bufsize;
1748 #endif
1749 }
1750
1751 static int
1752 dbri_get_props(void *hdl)
1753 {
1754
1755 return AUDIO_PROP_MMAP;
1756 }
1757
1758 static int
1759 dbri_trigger_output(void *hdl, void *start, void *end, int blksize,
1760 void (*intr)(void *), void *intrarg,
1761 const struct audio_params *param)
1762 {
1763 struct dbri_softc *sc = hdl;
1764 unsigned long count, current, num;
1765
1766 count = (unsigned long)(((char *)end - (char *)start));
1767 num = count / blksize;
1768
1769 DPRINTF("trigger_output(%lx %lx) : %d %ld %ld\n",
1770 (unsigned long)intr,
1771 (unsigned long)intrarg, blksize, count, num);
1772
1773 sc->sc_params = *param;
1774
1775 mmcodec_setcontrol(sc);
1776 mmcodec_init_data(sc);
1777 current = 0;
1778 while ((current < sc->sc_desc_used) &&
1779 (sc->sc_desc[current].buf != start))
1780 current++;
1781
1782 if (current < sc->sc_desc_used) {
1783 setup_ring(sc, 4, current, num, blksize, intr, intrarg);
1784 return 0;
1785 }
1786 return EINVAL;
1787 }
1788
1789 static u_int32_t
1790 reverse_bytes(u_int32_t b, int len)
1791 {
1792 switch (len) {
1793 case 32:
1794 b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16);
1795 case 16:
1796 b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8);
1797 case 8:
1798 b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4);
1799 case 4:
1800 b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2);
1801 case 2:
1802 b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1);
1803 case 1:
1804 case 0:
1805 break;
1806 default:
1807 DPRINTF("reverse_bytes: unsupported length\n");
1808 };
1809
1810 return (b);
1811 }
1812
1813 static void
1814 *dbri_malloc(void *v, int dir, size_t s, struct malloc_type *mt, int flags)
1815 {
1816 struct dbri_softc *sc = v;
1817 struct dbri_desc *dd = &sc->sc_desc[sc->sc_desc_used];
1818 int rseg;
1819
1820 if (bus_dmamap_create(sc->sc_dmat, s, 1, s, 0, BUS_DMA_NOWAIT,
1821 &dd->dmamap) == 0) {
1822 if (bus_dmamem_alloc(sc->sc_dmat, s, 0, 0, &dd->dmaseg,
1823 1, &rseg, BUS_DMA_NOWAIT) == 0) {
1824 if (bus_dmamem_map(sc->sc_dmat, &dd->dmaseg, rseg, s,
1825 &dd->buf, BUS_DMA_NOWAIT|BUS_DMA_COHERENT) == 0) {
1826 if (dd->buf!=NULL) {
1827 if (bus_dmamap_load(sc->sc_dmat,
1828 dd->dmamap, dd->buf, s, NULL,
1829 BUS_DMA_NOWAIT) == 0) {
1830 dd->len = s;
1831 dd->busy = 0;
1832 dd->callback = NULL;
1833 dd->dmabase =
1834 dd->dmamap->dm_segs[0].ds_addr;
1835 DPRINTF("dbri_malloc: using buffer %d\n",
1836 sc->sc_desc_used);
1837 sc->sc_desc_used++;
1838 return dd->buf;
1839 } else
1840 aprint_error("dbri_malloc: load failed\n");
1841 } else
1842 aprint_error("dbri_malloc: map returned NULL\n");
1843 } else
1844 aprint_error("dbri_malloc: map failed\n");
1845 bus_dmamem_free(sc->sc_dmat, &dd->dmaseg, rseg);
1846 } else
1847 aprint_error("dbri_malloc: malloc() failed\n");
1848 bus_dmamap_destroy(sc->sc_dmat, dd->dmamap);
1849 } else
1850 aprint_error("dbri_malloc: bus_dmamap_create() failed\n");
1851 return NULL;
1852 }
1853
1854 static void
1855 dbri_free(void *v, void *p, struct malloc_type *mt)
1856 {
1857 free(p, mt);
1858 }
1859
1860 static paddr_t
1861 dbri_mappage(void *v, void *mem, off_t off, int prot)
1862 {
1863 struct dbri_softc *sc = v;;
1864 int current;
1865
1866 if (off < 0)
1867 return -1;
1868
1869 current = 0;
1870 while ((current < sc->sc_desc_used) &&
1871 (sc->sc_desc[current].buf != mem))
1872 current++;
1873
1874 if (current < sc->sc_desc_used) {
1875 return bus_dmamem_mmap(sc->sc_dmat,
1876 &sc->sc_desc[current].dmaseg, 1, off, prot, BUS_DMA_WAITOK);
1877 }
1878
1879 return -1;
1880 }
1881
1882 static int
1883 dbri_open(void *cookie, int flags)
1884 {
1885 struct dbri_softc *sc = cookie;
1886
1887 dbri_bring_up(sc);
1888 return 0;
1889 }
1890
1891 static void
1892 dbri_close(void *cookie)
1893 {
1894 struct dbri_softc *sc = cookie;
1895
1896 dbri_set_power(sc, 0);
1897 }
1898
1899 static void
1900 dbri_powerhook(int why, void *cookie)
1901 {
1902 struct dbri_softc *sc = cookie;
1903
1904 switch(why)
1905 {
1906 case PWR_SUSPEND:
1907 case PWR_STANDBY:
1908 dbri_set_power(sc, 0);
1909 break;
1910 case PWR_RESUME:
1911 dbri_bring_up(sc);
1912 break;
1913 }
1914 }
1915
1916 #endif /* NAUDIO > 0 */
1917