dbri.c revision 1.14 1 /* $NetBSD: dbri.c,v 1.14 2007/07/12 22:58:50 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, 2007 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.14 2007/07/12 22:58:50 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_halt_input(void *);
148 static int dbri_getdev(void *, struct audio_device *);
149 static int dbri_set_port(void *, mixer_ctrl_t *);
150 static int dbri_get_port(void *, mixer_ctrl_t *);
151 static int dbri_query_devinfo(void *, mixer_devinfo_t *);
152 static size_t dbri_round_buffersize(void *, int, size_t);
153 static int dbri_get_props(void *);
154 static int dbri_open(void *, int);
155 static void dbri_close(void *);
156
157 static void setup_ring_xmit(struct dbri_softc *, int, int, int, int,
158 void (*)(void *), void *);
159 static void setup_ring_recv(struct dbri_softc *, int, int, int, int,
160 void (*)(void *), void *);
161
162 static int dbri_trigger_output(void *, void *, void *, int,
163 void (*)(void *), void *, const struct audio_params *);
164 static int dbri_trigger_input(void *, void *, void *, int,
165 void (*)(void *), void *, const struct audio_params *);
166
167 static void *dbri_malloc(void *, int, size_t, struct malloc_type *, int);
168 static void dbri_free(void *, void *, struct malloc_type *);
169 static paddr_t dbri_mappage(void *, void *, off_t, int);
170 static void dbri_set_power(struct dbri_softc *, int);
171 static void dbri_bring_up(struct dbri_softc *);
172 static void dbri_powerhook(int, void *);
173
174 /* stupid support routines */
175 static u_int32_t reverse_bytes(u_int32_t, int);
176
177 struct audio_device dbri_device = {
178 "CS4215",
179 "",
180 "dbri"
181 };
182
183 struct audio_hw_if dbri_hw_if = {
184 dbri_open,
185 dbri_close,
186 NULL, /* drain */
187 dbri_query_encoding,
188 dbri_set_params,
189 dbri_round_blocksize,
190 NULL, /* commit_settings */
191 NULL, /* init_output */
192 NULL, /* init_input */
193 NULL, /* start_output */
194 NULL, /* start_input */
195 dbri_halt_output,
196 dbri_halt_input,
197 NULL, /* speaker_ctl */
198 dbri_getdev,
199 NULL, /* setfd */
200 dbri_set_port,
201 dbri_get_port,
202 dbri_query_devinfo,
203 dbri_malloc,
204 dbri_free,
205 dbri_round_buffersize,
206 dbri_mappage,
207 dbri_get_props,
208 dbri_trigger_output,
209 dbri_trigger_input
210 };
211
212 CFATTACH_DECL(dbri, sizeof(struct dbri_softc),
213 dbri_match_sbus, dbri_attach_sbus, NULL, NULL);
214
215 #define DBRI_NFORMATS 4
216 static const struct audio_format dbri_formats[DBRI_NFORMATS] = {
217 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_BE, 16, 16,
218 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
219 48000}},
220 /* {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULAW, 8, 8,
221 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
222 48000}},
223 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ALAW, 8, 8,
224 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
225 48000}},
226 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR, 8, 8,
227 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
228 48000}},*/
229 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULAW, 8, 8,
230 1, AUFMT_MONAURAL, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
231 48000}},
232 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ALAW, 8, 8,
233 1, AUFMT_MONAURAL, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
234 48000}},
235 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR, 8, 8,
236 1, AUFMT_MONAURAL, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
237 48000}},
238 };
239
240 enum {
241 DBRI_OUTPUT_CLASS,
242 DBRI_VOL_OUTPUT,
243 DBRI_ENABLE_MONO,
244 DBRI_ENABLE_HEADPHONE,
245 DBRI_ENABLE_LINE,
246 DBRI_MONITOR_CLASS,
247 DBRI_VOL_MONITOR,
248 DBRI_INPUT_CLASS,
249 DBRI_INPUT_GAIN,
250 DBRI_INPUT_SELECT,
251 DBRI_RECORD_CLASS,
252 DBRI_ENUM_LAST
253 };
254
255 /*
256 * Autoconfig routines
257 */
258 static int
259 dbri_match_sbus(struct device *parent, struct cfdata *match, void *aux)
260 {
261 struct sbus_attach_args *sa = aux;
262 char *ver;
263 int i;
264
265 if (strncmp(DBRI_ROM_NAME_PREFIX, sa->sa_name, 9))
266 return (0);
267
268 ver = &sa->sa_name[9];
269
270 for (i = 0; dbri_supported[i][0] != '\0'; i++)
271 if (strcmp(dbri_supported[i], ver) == 0)
272 return (1);
273
274 return (0);
275 }
276
277 static void
278 dbri_attach_sbus(struct device *parent, struct device *self, void *aux)
279 {
280 struct dbri_softc *sc = (struct dbri_softc *)self;
281 struct sbus_attach_args *sa = aux;
282 bus_space_handle_t ioh;
283 bus_size_t size;
284 int error, rseg, pwr;
285 char *ver = &sa->sa_name[9];
286
287 sc->sc_iot = sa->sa_bustag;
288 sc->sc_dmat = sa->sa_dmatag;
289 sc->sc_powerstate = PWR_RESUME;
290
291 pwr = prom_getpropint(sa->sa_node,"pwr-on-auxio",0);
292 aprint_normal(": rev %s\n", ver);
293
294 if (pwr) {
295 /*
296 * we can control DBRI power via auxio and we're initially
297 * powered down
298 */
299
300 sc->sc_have_powerctl = 1;
301 sc->sc_powerstate = 0;
302 dbri_set_power(sc, 1);
303 powerhook_establish(self->dv_xname, dbri_powerhook, sc);
304 } else {
305 /* we can't control power so we're always up */
306 sc->sc_have_powerctl = 0;
307 sc->sc_powerstate = 1;
308 }
309
310 if (sa->sa_npromvaddrs)
311 ioh = (bus_space_handle_t)sa->sa_promvaddrs[0];
312 else {
313 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
314 sa->sa_offset, sa->sa_size,
315 BUS_SPACE_MAP_LINEAR, /*0,*/ &ioh) != 0) {
316 aprint_error("%s @ sbus: cannot map registers\n",
317 self->dv_xname);
318 return;
319 }
320 }
321
322 sc->sc_ioh = ioh;
323
324 size = sizeof(struct dbri_dma);
325
326 /* get a DMA handle */
327 if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
328 BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
329 aprint_error("%s: DMA map create error %d\n", self->dv_xname,
330 error);
331 return;
332 }
333
334 /* allocate DMA buffer */
335 if ((error = bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &sc->sc_dmaseg,
336 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
337 aprint_error("%s: DMA buffer alloc error %d\n",
338 self->dv_xname, error);
339 return;
340 }
341
342 /* map DMA buffer into CPU addressable space */
343 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dmaseg, rseg, size,
344 &sc->sc_membase,
345 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
346 aprint_error("%s: DMA buffer map error %d\n",
347 self->dv_xname, error);
348 return;
349 }
350
351 /* load the buffer */
352 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap,
353 sc->sc_membase, size, NULL,
354 BUS_DMA_NOWAIT)) != 0) {
355 aprint_error("%s: DMA buffer map load error %d\n",
356 self->dv_xname, error);
357 bus_dmamem_unmap(sc->sc_dmat, sc->sc_membase, size);
358 bus_dmamem_free(sc->sc_dmat, &sc->sc_dmaseg, rseg);
359 return;
360 }
361
362 /* map the registers into memory */
363
364 /* kernel virtual address of DMA buffer */
365 sc->sc_dma = (struct dbri_dma *)sc->sc_membase;
366 /* physical address of DMA buffer */
367 sc->sc_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr;
368 sc->sc_bufsiz = size;
369
370 sbus_establish(&sc->sc_sd, &sc->sc_dev);
371
372 bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_AUDIO, dbri_intr,
373 sc);
374
375 sc->sc_locked = 0;
376 sc->sc_desc_used = 0;
377 sc->sc_refcount = 0;
378 sc->sc_playing = 0;
379 sc->sc_recording = 0;
380 sc->sc_pmgrstate = PWR_RESUME;
381 config_interrupts(self, &dbri_config_interrupts);
382
383 return;
384 }
385
386 /*
387 * lowlevel routine to switch power for the DBRI chip
388 */
389 static void
390 dbri_set_power(struct dbri_softc *sc, int state)
391 {
392 int s;
393
394 if (sc->sc_have_powerctl == 0)
395 return;
396 if (sc->sc_powerstate == state)
397 return;
398
399 if (state) {
400 DPRINTF("%s: waiting to power up... ", sc->sc_dev.dv_xname);
401 s = splhigh();
402 *AUXIO4M_REG |= (AUXIO4M_MMX);
403 splx(s);
404 delay(10000);
405 DPRINTF("done (%02x)\n", *AUXIO4M_REG);
406 } else {
407 DPRINTF("%s: powering down\n", sc->sc_dev.dv_xname);
408 s = splhigh();
409 *AUXIO4M_REG &= ~AUXIO4M_MMX;
410 splx(s);
411 DPRINTF("done (%02x})\n", *AUXIO4M_REG);
412 }
413 sc->sc_powerstate = state;
414 }
415
416 /*
417 * power up and re-initialize the chip
418 */
419 static void
420 dbri_bring_up(struct dbri_softc *sc)
421 {
422
423 if (sc->sc_have_powerctl == 0)
424 return;
425 if (sc->sc_powerstate == 1)
426 return;
427
428 /* ok, we really need to do something */
429 dbri_set_power(sc, 1);
430
431 /*
432 * re-initialize the chip but skip all the probing, don't overwrite
433 * any other settings either
434 */
435 dbri_init(sc);
436 mmcodec_setgain(sc, 1);
437 mmcodec_pipe_init(sc);
438 mmcodec_init_data(sc);
439 mmcodec_setgain(sc, 0);
440 }
441
442 static void
443 dbri_config_interrupts(struct device *dev)
444 {
445 struct dbri_softc *sc = (struct dbri_softc *)dev;
446
447 dbri_init(sc);
448 mmcodec_init(sc);
449
450 /* Attach ourselves to the high level audio interface */
451 audio_attach_mi(&dbri_hw_if, sc, &sc->sc_dev);
452
453 /* power down until open() */
454 dbri_set_power(sc, 0);
455 return;
456 }
457
458 static int
459 dbri_intr(void *hdl)
460 {
461 struct dbri_softc *sc = hdl;
462 bus_space_tag_t iot = sc->sc_iot;
463 bus_space_handle_t ioh = sc->sc_ioh;
464 int x;
465
466 /* clear interrupt */
467 x = bus_space_read_4(iot, ioh, DBRI_REG1);
468 if (x & (DBRI_MRR | DBRI_MLE | DBRI_LBG | DBRI_MBE)) {
469 u_int32_t tmp;
470
471 if (x & DBRI_MRR)
472 aprint_debug("%s: multiple ack error on sbus\n",
473 sc->sc_dev.dv_xname);
474 if (x & DBRI_MLE)
475 aprint_debug("%s: multiple late error on sbus\n",
476 sc->sc_dev.dv_xname);
477 if (x & DBRI_LBG)
478 aprint_debug("%s: lost bus grant on sbus\n",
479 sc->sc_dev.dv_xname);
480 if (x & DBRI_MBE)
481 aprint_debug("%s: burst error on sbus\n",
482 sc->sc_dev.dv_xname);
483
484 /*
485 * Some of these errors disable the chip's circuitry.
486 * Re-enable the circuitry and keep on going.
487 */
488
489 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
490 tmp &= ~(DBRI_DISABLE_MASTER);
491 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
492 }
493
494 #if 0
495 if (!x & 1) /* XXX: DBRI_INTR_REQ */
496 return (1);
497 #endif
498
499 dbri_process_interrupt_buffer(sc);
500
501 return (1);
502 }
503
504 static int
505 dbri_init(struct dbri_softc *sc)
506 {
507 bus_space_tag_t iot = sc->sc_iot;
508 bus_space_handle_t ioh = sc->sc_ioh;
509 u_int32_t reg;
510 volatile u_int32_t *cmd;
511 bus_addr_t dmaaddr;
512 int n;
513
514 dbri_reset(sc);
515
516 cmd = dbri_command_lock(sc);
517
518 /* XXX: Initialize interrupt ring buffer */
519 sc->sc_dma->intr[0] = (u_int32_t)sc->sc_dmabase + dbri_dma_off(intr, 0);
520 sc->sc_irqp = 1;
521
522 /* Initialize pipes */
523 for (n = 0; n < DBRI_PIPE_MAX; n++)
524 sc->sc_pipe[n].desc = sc->sc_pipe[n].next = -1;
525
526 for (n = 1; n < DBRI_INT_BLOCKS; n++) {
527 sc->sc_dma->intr[n] = 0;
528 }
529
530 /* Disable all SBus bursts */
531 /* XXX 16 byte bursts cause errors, the rest works */
532 reg = bus_space_read_4(iot, ioh, DBRI_REG0);
533
534 /*reg &= ~(DBRI_BURST_4 | DBRI_BURST_8 | DBRI_BURST_16);*/
535 reg |= (DBRI_BURST_4 | DBRI_BURST_8);
536 bus_space_write_4(iot, ioh, DBRI_REG0, reg);
537
538 /* setup interrupt queue */
539 dmaaddr = (u_int32_t)sc->sc_dmabase + dbri_dma_off(intr, 0);
540 *(cmd++) = DBRI_CMD(DBRI_COMMAND_IIQ, 0, 0);
541 *(cmd++) = dmaaddr;
542
543 dbri_command_send(sc, cmd);
544 return (0);
545 }
546
547 static int
548 dbri_reset(struct dbri_softc *sc)
549 {
550 int bail = 0;
551
552 bus_space_tag_t iot = sc->sc_iot;
553 bus_space_handle_t ioh = sc->sc_ioh;
554
555 bus_space_write_4(iot, ioh, DBRI_REG0, DBRI_SOFT_RESET);
556 while ((bus_space_read_4(iot, ioh, DBRI_REG0) & DBRI_SOFT_RESET) &&
557 (bail < 100000)) {
558 bail++;
559 delay(10);
560 }
561 if (bail == 100000) aprint_error("%s: reset timed out\n",
562 sc->sc_dev.dv_xname);
563 return (0);
564 }
565
566 static volatile u_int32_t *
567 dbri_command_lock(struct dbri_softc *sc)
568 {
569
570 if (sc->sc_locked)
571 aprint_debug("%s: command buffer locked\n",
572 sc->sc_dev.dv_xname);
573
574 sc->sc_locked++;
575
576 return (&sc->sc_dma->command[0]);
577 }
578
579 static void
580 dbri_command_send(struct dbri_softc *sc, volatile u_int32_t *cmd)
581 {
582 bus_space_handle_t ioh = sc->sc_ioh;
583 bus_space_tag_t iot = sc->sc_iot;
584 int maxloops = 1000000;
585 int x;
586
587 x = splaudio();
588
589 sc->sc_locked--;
590
591 if (sc->sc_locked != 0) {
592 aprint_error("%s: command buffer improperly locked\n",
593 sc->sc_dev.dv_xname);
594 } else if ((cmd - &sc->sc_dma->command[0]) >= DBRI_NUM_COMMANDS - 1) {
595 aprint_error("%s: command buffer overflow\n",
596 sc->sc_dev.dv_xname);
597 } else {
598 *(cmd++) = DBRI_CMD(DBRI_COMMAND_PAUSE, 0, 0);
599 *(cmd++) = DBRI_CMD(DBRI_COMMAND_WAIT, 1, 0);
600 sc->sc_waitseen = 0;
601 bus_space_write_4(iot, ioh, DBRI_REG8, sc->sc_dmabase);
602 while ((--maxloops) > 0 &&
603 (bus_space_read_4(iot, ioh, DBRI_REG0)
604 & DBRI_COMMAND_VALID)) {
605 bus_space_barrier(iot, ioh, DBRI_REG0, 4,
606 BUS_SPACE_BARRIER_READ);
607 delay(1000);
608 }
609
610 if (maxloops == 0) {
611 aprint_error(
612 "%s: chip never completed command buffer\n",
613 sc->sc_dev.dv_xname);
614 } else {
615
616 DPRINTF("%s: command completed\n",
617 sc->sc_dev.dv_xname);
618
619 while ((--maxloops) > 0 && (!sc->sc_waitseen))
620 dbri_process_interrupt_buffer(sc);
621 if (maxloops == 0) {
622 aprint_error("%s: chip never acked WAIT\n",
623 sc->sc_dev.dv_xname);
624 }
625 }
626 }
627
628 splx(x);
629
630 return;
631 }
632
633 static void
634 dbri_process_interrupt_buffer(struct dbri_softc *sc)
635 {
636 int32_t i;
637
638 while ((i = sc->sc_dma->intr[sc->sc_irqp]) != 0) {
639 sc->sc_dma->intr[sc->sc_irqp] = 0;
640 sc->sc_irqp++;
641
642 if (sc->sc_irqp == DBRI_INT_BLOCKS)
643 sc->sc_irqp = 1;
644 else if ((sc->sc_irqp & (DBRI_INT_BLOCKS - 1)) == 0)
645 sc->sc_irqp++;
646
647 dbri_process_interrupt(sc, i);
648 }
649
650 return;
651 }
652
653 static void
654 dbri_process_interrupt(struct dbri_softc *sc, int32_t i)
655 {
656 #if 0
657 const int liu_states[] = { 1, 0, 8, 3, 4, 5, 6, 7 };
658 #endif
659 int val = DBRI_INTR_GETVAL(i);
660 int channel = DBRI_INTR_GETCHAN(i);
661 int command = DBRI_INTR_GETCMD(i);
662 int code = DBRI_INTR_GETCODE(i);
663 #if 0
664 int rval = DBRI_INTR_GETRVAL(i);
665 #endif
666 if (channel == DBRI_INTR_CMD && command == DBRI_COMMAND_WAIT)
667 sc->sc_waitseen++;
668
669 switch (code) {
670 case DBRI_INTR_XCMP: /* transmission complete */
671 {
672 int td;
673 struct dbri_desc *dd;
674
675 td = sc->sc_pipe[channel].desc;
676 dd = &sc->sc_desc[td];
677
678 if (dd->callback != NULL) {
679 dd->callback(dd->callback_args);
680 } else
681 DPRINTF("!");
682 break;
683 }
684 case DBRI_INTR_FXDT: /* fixed data change */
685 DPRINTF("dbri_intr: Fixed data change (%d: %x)\n", channel,
686 val);
687 #if 0
688 printf("reg: %08x\n", sc->sc_mm.status);
689 #endif
690 if (sc->sc_pipe[channel].sdp & DBRI_SDP_MSB)
691 val = reverse_bytes(val, sc->sc_pipe[channel].length);
692 if (sc->sc_pipe[channel].prec)
693 *(sc->sc_pipe[channel].prec) = val;
694 #ifndef DBRI_SPIN
695 DPRINTF("%s: wakeup %p\n", sc->sc_dev.dv_xname, sc);
696 wakeup(sc);
697 #endif
698 break;
699 case DBRI_INTR_SBRI:
700 DPRINTF("dbri_intr: SBRI\n");
701 break;
702 case DBRI_INTR_BRDY:
703 {
704 int td;
705 struct dbri_desc *dd;
706
707 td = sc->sc_pipe[channel].desc;
708 dd = &sc->sc_desc[td];
709
710 if (dd->callback != NULL)
711 dd->callback(dd->callback_args);
712 break;
713 }
714 case DBRI_INTR_UNDR:
715 {
716 volatile u_int32_t *cmd;
717 int td = sc->sc_pipe[channel].desc;
718
719 DPRINTF("%s: DBRI_INTR_UNDR\n", sc->sc_dev.dv_xname);
720
721 sc->sc_dma->xmit[td].status = 0;
722
723 cmd = dbri_command_lock(sc);
724 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0,
725 sc->sc_pipe[channel].sdp |
726 DBRI_SDP_VALID_POINTER |
727 DBRI_SDP_CLEAR |
728 DBRI_SDP_2SAME);
729 *(cmd++) = sc->sc_dmabase + dbri_dma_off(xmit, td);
730 dbri_command_send(sc, cmd);
731 break;
732 }
733 case DBRI_INTR_CMDI:
734 DPRINTF("ok");
735 break;
736 default:
737
738 aprint_error("%s: unknown interrupt code %d\n",
739 sc->sc_dev.dv_xname, code);
740 break;
741 }
742
743 return;
744 }
745
746 /*
747 * mmcodec stuff
748 */
749
750 static int
751 mmcodec_init(struct dbri_softc *sc)
752 {
753 bus_space_handle_t ioh = sc->sc_ioh;
754 bus_space_tag_t iot = sc->sc_iot;
755 u_int32_t reg2;
756 int bail;
757
758 reg2 = bus_space_read_4(iot, ioh, DBRI_REG2);
759 DPRINTF("mmcodec_init: PIO reads %x\n", reg2);
760
761 if (reg2 & DBRI_PIO2) {
762 aprint_normal("%s: onboard CS4215 detected\n",
763 sc->sc_dev.dv_xname);
764 sc->sc_mm.onboard = 1;
765 }
766
767 if (reg2 & DBRI_PIO0) {
768 aprint_normal("%s: speakerbox detected\n",
769 sc->sc_dev.dv_xname);
770 sc->sc_mm.onboard = 0;
771 }
772
773 if ((reg2 & DBRI_PIO2) && (reg2 & DBRI_PIO0)) {
774 aprint_normal("%s: using speakerbox\n",
775 sc->sc_dev.dv_xname);
776 bus_space_write_4(iot, ioh, DBRI_REG2, DBRI_PIO2_ENABLE);
777 sc->sc_mm.onboard = 0;
778 }
779
780 if (!(reg2 & (DBRI_PIO0|DBRI_PIO2))) {
781 aprint_normal("%s: no mmcodec found\n", sc->sc_dev.dv_xname);
782 return -1;
783 }
784
785 sc->sc_version = 0xff;
786
787 mmcodec_pipe_init(sc);
788 mmcodec_default(sc);
789
790 sc->sc_mm.offset = sc->sc_mm.onboard ? 0 : 8;
791
792 /*
793 * mmcodec_setcontrol() sometimes fails right after powerup
794 * so we just try again until we either get a useful response or run
795 * out of time
796 */
797 bail = 0;
798 while (mmcodec_setcontrol(sc) == -1 || sc->sc_version == 0xff) {
799
800 bail++;
801 if (bail > 100) {
802 DPRINTF("%s: cs4215 probe failed at offset %d\n",
803 sc->sc_dev.dv_xname, sc->sc_mm.offset);
804 return (-1);
805 }
806 delay(10000);
807 }
808
809 aprint_normal("%s: cs4215 rev %c found at offset %d\n",
810 sc->sc_dev.dv_xname, 0x43 + (sc->sc_version & 0xf), sc->sc_mm.offset);
811
812 /* set some sane defaults for mmcodec_init_data */
813 sc->sc_params.channels = 2;
814 sc->sc_params.precision = 16;
815
816 mmcodec_init_data(sc);
817
818 return (0);
819 }
820
821 static void
822 mmcodec_init_data(struct dbri_softc *sc)
823 {
824 bus_space_tag_t iot = sc->sc_iot;
825 bus_space_handle_t ioh = sc->sc_ioh;
826 u_int32_t tmp;
827 int data_width;
828
829 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
830 tmp &= ~(DBRI_CHI_ACTIVATE); /* disable CHI */
831 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
832
833 /* switch CS4215 to data mode - set PIO3 to 1 */
834 tmp = DBRI_PIO_ENABLE_ALL | DBRI_PIO1 | DBRI_PIO3;
835
836 /* XXX */
837 tmp |= (sc->sc_mm.onboard ? DBRI_PIO0 : DBRI_PIO2);
838
839 bus_space_write_4(iot, ioh, DBRI_REG2, tmp);
840 chi_reset(sc, CHIslave, 128);
841
842 data_width = sc->sc_params.channels * sc->sc_params.precision;
843
844 if ((data_width != 32) && (data_width != 8))
845 aprint_error("%s: data_width is %d\n", __func__, data_width);
846
847 pipe_ts_link(sc, 20, PIPEoutput, 16, 32, sc->sc_mm.offset + 32);
848 pipe_ts_link(sc, 4, PIPEoutput, 16, data_width, sc->sc_mm.offset);
849 pipe_ts_link(sc, 6, PIPEinput, 16, data_width, sc->sc_mm.offset);
850 pipe_ts_link(sc, 21, PIPEinput, 16, 32, sc->sc_mm.offset + 32);
851
852 pipe_receive_fixed(sc, 21, &sc->sc_mm.status);
853
854 mmcodec_setgain(sc, 0);
855
856 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
857 tmp |= DBRI_CHI_ACTIVATE;
858 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
859
860 return;
861 }
862
863 static void
864 mmcodec_pipe_init(struct dbri_softc *sc)
865 {
866
867 pipe_setup(sc, 4, DBRI_SDP_MEM | DBRI_SDP_TO_SER | DBRI_SDP_MSB);
868 pipe_setup(sc, 20, DBRI_SDP_FIXED | DBRI_SDP_TO_SER | DBRI_SDP_MSB);
869 pipe_setup(sc, 6, DBRI_SDP_MEM | DBRI_SDP_FROM_SER | DBRI_SDP_MSB);
870 pipe_setup(sc, 21, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB);
871
872 pipe_setup(sc, 17, DBRI_SDP_FIXED | DBRI_SDP_TO_SER | DBRI_SDP_MSB);
873 pipe_setup(sc, 18, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB);
874 pipe_setup(sc, 19, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB);
875
876 sc->sc_mm.status = 0;
877
878 pipe_receive_fixed(sc, 18, &sc->sc_mm.status);
879 pipe_receive_fixed(sc, 19, &sc->sc_mm.version);
880
881 return;
882 }
883
884 static void
885 mmcodec_default(struct dbri_softc *sc)
886 {
887 struct cs4215_state *mm = &sc->sc_mm;
888
889 /*
890 * no action, memory resetting only
891 *
892 * data time slots 5-8
893 * speaker, line and headphone enable. set gain to half.
894 * input is line
895 */
896 mm->d.bdata[0] = sc->sc_latt = 0x20 | CS4215_HE | CS4215_LE;
897 mm->d.bdata[1] = sc->sc_ratt = 0x20 | CS4215_SE;
898 sc->sc_linp = 128;
899 sc->sc_rinp = 128;
900 sc->sc_monitor = 0;
901 sc->sc_input = 1; /* line */
902 mm->d.bdata[2] = (CS4215_LG((sc->sc_linp >> 4)) & 0x0f) |
903 ((sc->sc_input == 2) ? CS4215_IS : 0) | CS4215_PIO0 | CS4215_PIO1;
904 mm->d.bdata[3] = (CS4215_RG((sc->sc_rinp >> 4) & 0x0f)) |
905 CS4215_MA(15 - ((sc->sc_monitor >> 4) & 0x0f));
906
907
908 /*
909 * control time slots 1-4
910 *
911 * 0: default I/O voltage scale
912 * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled
913 * 2: serial enable, CHI master, 128 bits per frame, clock 1
914 * 3: tests disabled
915 */
916 mm->c.bcontrol[0] = CS4215_RSRVD_1 | CS4215_MLB;
917 mm->c.bcontrol[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval;
918 mm->c.bcontrol[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal;
919 mm->c.bcontrol[3] = 0;
920
921 return;
922 }
923
924 static void
925 mmcodec_setgain(struct dbri_softc *sc, int mute)
926 {
927 if (mute) {
928 /* disable all outputs, max. attenuation */
929 sc->sc_mm.d.bdata[0] = sc->sc_latt | 63;
930 sc->sc_mm.d.bdata[1] = sc->sc_ratt | 63;
931 } else {
932
933 sc->sc_mm.d.bdata[0] = sc->sc_latt;
934 sc->sc_mm.d.bdata[1] = sc->sc_ratt;
935 }
936
937 /* input stuff */
938 sc->sc_mm.d.bdata[2] = CS4215_LG((sc->sc_linp >> 4) & 0x0f) |
939 ((sc->sc_input == 2) ? CS4215_IS : 0) | CS4215_PIO0 | CS4215_PIO1;
940 sc->sc_mm.d.bdata[3] = (CS4215_RG((sc->sc_rinp >> 4)) & 0x0f) |
941 (CS4215_MA(15 - ((sc->sc_monitor >> 4) & 0x0f)));
942
943 if (sc->sc_powerstate == 0)
944 return;
945 pipe_transmit_fixed(sc, 20, sc->sc_mm.d.ldata);
946
947 DPRINTF("mmcodec_setgain: %08x\n", sc->sc_mm.d.ldata);
948 /* give the chip some time to execute the command */
949 delay(250);
950
951 return;
952 }
953
954 static int
955 mmcodec_setcontrol(struct dbri_softc *sc)
956 {
957 bus_space_tag_t iot = sc->sc_iot;
958 bus_space_handle_t ioh = sc->sc_ioh;
959 u_int32_t val;
960 u_int32_t tmp;
961 #if DBRI_SPIN
962 int i;
963 #endif
964
965 /*
966 * Temporarily mute outputs and wait 125 us to make sure that it
967 * happens. This avoids clicking noises.
968 */
969 mmcodec_setgain(sc, 1);
970 delay(125);
971
972 /* enable control mode */
973 val = DBRI_PIO_ENABLE_ALL | DBRI_PIO1; /* was PIO1 */
974
975 /* XXX */
976 val |= (sc->sc_mm.onboard ? DBRI_PIO0 : DBRI_PIO2);
977
978 bus_space_write_4(iot, ioh, DBRI_REG2, val);
979
980 delay(34);
981
982 /*
983 * in control mode, the cs4215 is the slave device, so the
984 * DBRI must act as the CHI master.
985 *
986 * in data mode, the cs4215 must be the CHI master to insure
987 * that the data stream is in sync with its codec
988 */
989 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
990 tmp &= ~DBRI_COMMAND_CHI;
991 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
992
993 chi_reset(sc, CHImaster, 128);
994
995 /* control mode */
996 pipe_ts_link(sc, 17, PIPEoutput, 16, 32, sc->sc_mm.offset);
997 pipe_ts_link(sc, 18, PIPEinput, 16, 8, sc->sc_mm.offset);
998 pipe_ts_link(sc, 19, PIPEinput, 16, 8, sc->sc_mm.offset + 48);
999
1000 /* wait for the chip to echo back CLB as zero */
1001 sc->sc_mm.c.bcontrol[0] &= ~CS4215_CLB;
1002 pipe_transmit_fixed(sc, 17, sc->sc_mm.c.lcontrol);
1003
1004 tmp = bus_space_read_4(iot, ioh, DBRI_REG0);
1005 tmp |= DBRI_CHI_ACTIVATE;
1006 bus_space_write_4(iot, ioh, DBRI_REG0, tmp);
1007
1008 #if DBRI_SPIN
1009 i = 1024;
1010 while (((sc->sc_mm.status & 0xe4) != 0x20) && --i) {
1011 delay(125);
1012 }
1013
1014 if (i == 0) {
1015 DPRINTF("%s: cs4215 didn't respond to CLB (0x%02x)\n",
1016 sc->sc_dev.dv_xname, sc->sc_mm.status);
1017 return (-1);
1018 }
1019 #else
1020 while ((sc->sc_mm.status & 0xe4) != 0x20) {
1021 DPRINTF("%s: tsleep %p\n", sc->sc_dev.dv_xname, sc);
1022 tsleep(sc, PCATCH | PZERO, "dbrifxdt", 0);
1023 }
1024 #endif
1025
1026 /* copy the version information before it becomes unreadable again */
1027 sc->sc_version = sc->sc_mm.version;
1028
1029 /* terminate cs4215 control mode */
1030 sc->sc_mm.c.bcontrol[0] |= CS4215_CLB;
1031 pipe_transmit_fixed(sc, 17, sc->sc_mm.c.lcontrol);
1032
1033 /* two frames of control info @ 8kHz frame rate = 250us delay */
1034 delay(250);
1035
1036 mmcodec_setgain(sc, 0);
1037
1038 return (0);
1039
1040 }
1041
1042 /*
1043 * CHI combo
1044 */
1045 static void
1046 chi_reset(struct dbri_softc *sc, enum ms ms, int bpf)
1047 {
1048 volatile u_int32_t *cmd;
1049 int val;
1050 int clockrate, divisor;
1051
1052 cmd = dbri_command_lock(sc);
1053
1054 /* set CHI anchor: pipe 16 */
1055 val = DBRI_DTS_VI | DBRI_DTS_INS | DBRI_DTS_PRVIN(16) | DBRI_PIPE(16);
1056 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val);
1057 *(cmd++) = DBRI_TS_ANCHOR | DBRI_TS_NEXT(16);
1058 *(cmd++) = 0;
1059
1060 val = DBRI_DTS_VO | DBRI_DTS_INS | DBRI_DTS_PRVOUT(16) | DBRI_PIPE(16);
1061 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val);
1062 *(cmd++) = 0;
1063 *(cmd++) = DBRI_TS_ANCHOR | DBRI_TS_NEXT(16);
1064
1065 sc->sc_pipe[16].sdp = 1;
1066 sc->sc_pipe[16].next = 16;
1067 sc->sc_chi_pipe_in = 16;
1068 sc->sc_chi_pipe_out = 16;
1069
1070 switch (ms) {
1071 case CHIslave:
1072 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CHI, 0, DBRI_CHI_CHICM(0));
1073 break;
1074 case CHImaster:
1075 clockrate = bpf * 8;
1076 divisor = 12288 / clockrate;
1077
1078 if (divisor > 255 || divisor * clockrate != 12288)
1079 aprint_error("%s: illegal bits-per-frame %d\n",
1080 sc->sc_dev.dv_xname, bpf);
1081
1082 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CHI, 0,
1083 DBRI_CHI_CHICM(divisor) | DBRI_CHI_FD | DBRI_CHI_BPF(bpf));
1084 break;
1085 default:
1086 aprint_error("%s: unknown value for ms!\n",
1087 sc->sc_dev.dv_xname);
1088 break;
1089 }
1090
1091 sc->sc_chi_bpf = bpf;
1092
1093 /* CHI data mode */
1094 *(cmd++) = DBRI_CMD(DBRI_COMMAND_PAUSE, 0, 0);
1095 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CDM, 0,
1096 DBRI_CDM_XCE | DBRI_CDM_XEN | DBRI_CDM_REN);
1097
1098 dbri_command_send(sc, cmd);
1099
1100 return;
1101 }
1102
1103 /*
1104 * pipe stuff
1105 */
1106 static void
1107 pipe_setup(struct dbri_softc *sc, int pipe, int sdp)
1108 {
1109 DPRINTF("pipe setup: %d\n", pipe);
1110 if (pipe < 0 || pipe >= DBRI_PIPE_MAX) {
1111 aprint_error("%s: illegal pipe number %d\n",
1112 sc->sc_dev.dv_xname, pipe);
1113 return;
1114 }
1115
1116 if ((sdp & 0xf800) != sdp)
1117 aprint_error("%s: strange SDP value %d\n", sc->sc_dev.dv_xname,
1118 sdp);
1119
1120 if (DBRI_SDP_MODE(sdp) == DBRI_SDP_FIXED &&
1121 !(sdp & DBRI_SDP_TO_SER))
1122 sdp |= DBRI_SDP_CHANGE;
1123
1124 sdp |= DBRI_PIPE(pipe);
1125
1126 sc->sc_pipe[pipe].sdp = sdp;
1127 sc->sc_pipe[pipe].desc = -1;
1128
1129 pipe_reset(sc, pipe);
1130
1131 return;
1132 }
1133
1134 static void
1135 pipe_reset(struct dbri_softc *sc, int pipe)
1136 {
1137 struct dbri_desc *dd;
1138 int sdp;
1139 int desc;
1140 volatile u_int32_t *cmd;
1141
1142 if (pipe < 0 || pipe >= DBRI_PIPE_MAX) {
1143 aprint_error("%s: illegal pipe number %d\n",
1144 sc->sc_dev.dv_xname, pipe);
1145 return;
1146 }
1147
1148 sdp = sc->sc_pipe[pipe].sdp;
1149 if (sdp == 0) {
1150 aprint_error("%s: can not reset uninitialized pipe %d\n",
1151 sc->sc_dev.dv_xname, pipe);
1152 return;
1153 }
1154
1155 cmd = dbri_command_lock(sc);
1156 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0,
1157 sdp | DBRI_SDP_CLEAR | DBRI_SDP_VALID_POINTER);
1158 *(cmd++) = 0;
1159 dbri_command_send(sc, cmd);
1160
1161 desc = sc->sc_pipe[pipe].desc;
1162
1163 dd = &sc->sc_desc[desc];
1164
1165 dd->busy = 0;
1166
1167 #if 0
1168 if (dd->callback)
1169 (*dd->callback)(dd->callback_args);
1170 #endif
1171
1172 sc->sc_pipe[pipe].desc = -1;
1173
1174 return;
1175 }
1176
1177 static void
1178 pipe_receive_fixed(struct dbri_softc *sc, int pipe, volatile u_int32_t *prec)
1179 {
1180
1181 if (pipe < DBRI_PIPE_MAX / 2 || pipe >= DBRI_PIPE_MAX) {
1182 aprint_error("%s: illegal pipe number %d\n",
1183 sc->sc_dev.dv_xname, pipe);
1184 return;
1185 }
1186
1187 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) != DBRI_SDP_FIXED) {
1188 aprint_error("%s: non-fixed pipe %d\n", sc->sc_dev.dv_xname,
1189 pipe);
1190 return;
1191 }
1192
1193 if (sc->sc_pipe[pipe].sdp & DBRI_SDP_TO_SER) {
1194 aprint_error("%s: can not receive on transmit pipe %d\b",
1195 sc->sc_dev.dv_xname, pipe);
1196 return;
1197 }
1198
1199 sc->sc_pipe[pipe].prec = prec;
1200
1201 return;
1202 }
1203
1204 static void
1205 pipe_transmit_fixed(struct dbri_softc *sc, int pipe, u_int32_t data)
1206 {
1207 volatile u_int32_t *cmd;
1208
1209 if (pipe < DBRI_PIPE_MAX / 2 || pipe >= DBRI_PIPE_MAX) {
1210 aprint_error("%s: illegal pipe number %d\n",
1211 sc->sc_dev.dv_xname, pipe);
1212 return;
1213 }
1214
1215 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) == 0) {
1216 aprint_error("%s: uninitialized pipe %d\n",
1217 sc->sc_dev.dv_xname, pipe);
1218 return;
1219 }
1220
1221 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) != DBRI_SDP_FIXED) {
1222 aprint_error("%s: non-fixed pipe %d\n", sc->sc_dev.dv_xname,
1223 pipe);
1224 return;
1225 }
1226
1227 if (!(sc->sc_pipe[pipe].sdp & DBRI_SDP_TO_SER)) {
1228 aprint_error("%s: called on receive pipe %d\n",
1229 sc->sc_dev.dv_xname, pipe);
1230 return;
1231 }
1232
1233 if (sc->sc_pipe[pipe].sdp & DBRI_SDP_MSB)
1234 data = reverse_bytes(data, sc->sc_pipe[pipe].length);
1235
1236 cmd = dbri_command_lock(sc);
1237 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SSP, 0, pipe);
1238 *(cmd++) = data;
1239
1240 dbri_command_send(sc, cmd);
1241
1242 return;
1243 }
1244
1245 static void
1246 setup_ring_xmit(struct dbri_softc *sc, int pipe, int which, int num, int blksz,
1247 void (*callback)(void *), void *callback_args)
1248 {
1249 volatile u_int32_t *cmd;
1250 int x, i;
1251 int td;
1252 int td_first, td_last;
1253 bus_addr_t dmabuf, dmabase;
1254 struct dbri_desc *dd = &sc->sc_desc[which];
1255
1256 switch (pipe) {
1257 case 4:
1258 /* output, offset 0 */
1259 break;
1260 default:
1261 aprint_error("%s: illegal pipe number (%d)\n",
1262 __func__, pipe);
1263 return;
1264 }
1265
1266 td = 0;
1267 td_first = td_last = -1;
1268
1269 if (sc->sc_pipe[pipe].sdp == 0) {
1270 aprint_error("%s: uninitialized pipe %d\n",
1271 sc->sc_dev.dv_xname, pipe);
1272 return;
1273 }
1274
1275 dmabuf = dd->dmabase;
1276 dmabase = sc->sc_dmabase;
1277 td = 0;
1278
1279 for (i = 0; i < (num - 1); i++) {
1280
1281 sc->sc_dma->xmit[i].flags = TX_BCNT(blksz)
1282 | TX_EOF | TX_BINT;
1283 sc->sc_dma->xmit[i].ba = dmabuf;
1284 sc->sc_dma->xmit[i].nda = dmabase + dbri_dma_off(xmit, i + 1);
1285 sc->sc_dma->xmit[i].status = 0;
1286
1287 td_last = td;
1288 dmabuf += blksz;
1289 }
1290
1291 sc->sc_dma->xmit[i].flags = TX_BCNT(blksz) | TX_EOF | TX_BINT;
1292
1293 sc->sc_dma->xmit[i].ba = dmabuf;
1294 sc->sc_dma->xmit[i].nda = dmabase + dbri_dma_off(xmit, 0);
1295 sc->sc_dma->xmit[i].status = 0;
1296
1297 dd->callback = callback;
1298 dd->callback_args = callback_args;
1299
1300 x = splaudio();
1301
1302 /* the pipe shouldn't be active */
1303 if (pipe_active(sc, pipe)) {
1304 aprint_error("pipe active (CDP)\n");
1305 /* pipe is already active */
1306 #if 0
1307 td_last = sc->sc_pipe[pipe].desc;
1308 while (sc->sc_desc[td_last].next != -1)
1309 td_last = sc->sc_desc[td_last].next;
1310
1311 sc->sc_desc[td_last].next = td_first;
1312 sc->sc_dma->desc[td_last].nda =
1313 sc->sc_dmabase + dbri_dma_off(desc, td_first);
1314
1315 cmd = dbri_command_lock(sc);
1316 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CDP, 0, pipe);
1317 dbri_command_send(sc, cmd);
1318 #endif
1319 } else {
1320 /*
1321 * pipe isn't active - issue an SDP command to start our
1322 * chain of TDs running
1323 */
1324 sc->sc_pipe[pipe].desc = which;
1325 cmd = dbri_command_lock(sc);
1326 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0,
1327 sc->sc_pipe[pipe].sdp |
1328 DBRI_SDP_VALID_POINTER |
1329 DBRI_SDP_EVERY |
1330 DBRI_SDP_CLEAR);
1331 *(cmd++) = sc->sc_dmabase + dbri_dma_off(xmit, 0);
1332 dbri_command_send(sc, cmd);
1333 DPRINTF("%s: starting DMA\n", __func__);
1334 }
1335
1336 splx(x);
1337
1338 return;
1339 }
1340
1341 static void
1342 setup_ring_recv(struct dbri_softc *sc, int pipe, int which, int num, int blksz,
1343 void (*callback)(void *), void *callback_args)
1344 {
1345 volatile u_int32_t *cmd;
1346 int x, i;
1347 int td_first, td_last;
1348 bus_addr_t dmabuf, dmabase;
1349 struct dbri_desc *dd = &sc->sc_desc[which];
1350
1351 switch (pipe) {
1352 case 6:
1353 break;
1354 default:
1355 aprint_error("%s: illegal pipe number (%d)\n",
1356 __func__, pipe);
1357 return;
1358 }
1359
1360 td_first = td_last = -1;
1361
1362 if (sc->sc_pipe[pipe].sdp == 0) {
1363 aprint_error("%s: uninitialized pipe %d\n",
1364 sc->sc_dev.dv_xname, pipe);
1365 return;
1366 }
1367
1368 dmabuf = dd->dmabase;
1369 dmabase = sc->sc_dmabase;
1370
1371 for (i = 0; i < (num - 1); i++) {
1372
1373 sc->sc_dma->recv[i].flags = RX_BSIZE(blksz) | RX_FINAL;
1374 sc->sc_dma->recv[i].ba = dmabuf;
1375 sc->sc_dma->recv[i].nda = dmabase + dbri_dma_off(recv, i + 1);
1376 sc->sc_dma->recv[i].status = RX_EOF;
1377
1378 td_last = i;
1379 dmabuf += blksz;
1380 }
1381
1382 sc->sc_dma->recv[i].flags = RX_BSIZE(blksz) | RX_FINAL;
1383
1384 sc->sc_dma->recv[i].ba = dmabuf;
1385 sc->sc_dma->recv[i].nda = dmabase + dbri_dma_off(recv, 0);
1386 sc->sc_dma->recv[i].status = RX_EOF;
1387
1388 dd->callback = callback;
1389 dd->callback_args = callback_args;
1390
1391 x = splaudio();
1392
1393 /* the pipe shouldn't be active */
1394 if (pipe_active(sc, pipe)) {
1395 aprint_error("pipe active (CDP)\n");
1396 /* pipe is already active */
1397 #if 0
1398 td_last = sc->sc_pipe[pipe].desc;
1399 while (sc->sc_desc[td_last].next != -1)
1400 td_last = sc->sc_desc[td_last].next;
1401
1402 sc->sc_desc[td_last].next = td_first;
1403 sc->sc_dma->desc[td_last].nda =
1404 sc->sc_dmabase + dbri_dma_off(desc, td_first);
1405
1406 cmd = dbri_command_lock(sc);
1407 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CDP, 0, pipe);
1408 dbri_command_send(sc, cmd);
1409 #endif
1410 } else {
1411 /*
1412 * pipe isn't active - issue an SDP command to start our
1413 * chain of TDs running
1414 */
1415 sc->sc_pipe[pipe].desc = which;
1416 cmd = dbri_command_lock(sc);
1417 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0,
1418 sc->sc_pipe[pipe].sdp |
1419 DBRI_SDP_VALID_POINTER |
1420 DBRI_SDP_EVERY |
1421 DBRI_SDP_CLEAR);
1422 *(cmd++) = sc->sc_dmabase + dbri_dma_off(recv, 0);
1423 dbri_command_send(sc, cmd);
1424 DPRINTF("%s: starting DMA\n", __func__);
1425 }
1426
1427 splx(x);
1428
1429 return;
1430 }
1431
1432 static void
1433 pipe_ts_link(struct dbri_softc *sc, int pipe, enum io dir, int basepipe,
1434 int len, int cycle)
1435 {
1436 volatile u_int32_t *cmd;
1437 int prevpipe, nextpipe;
1438 int val;
1439
1440 DPRINTF("%s: %d\n", __func__, pipe);
1441 if (pipe < 0 || pipe >= DBRI_PIPE_MAX ||
1442 basepipe < 0 || basepipe >= DBRI_PIPE_MAX) {
1443 aprint_error("%s: illegal pipe numbers (%d, %d)\n",
1444 sc->sc_dev.dv_xname, pipe, basepipe);
1445 return;
1446 }
1447
1448 if (sc->sc_pipe[pipe].sdp == 0 || sc->sc_pipe[basepipe].sdp == 0) {
1449 aprint_error("%s: uninitialized pipe (%d, %d)\n",
1450 sc->sc_dev.dv_xname, pipe, basepipe);
1451 return;
1452 }
1453
1454 if (basepipe == 16 && dir == PIPEoutput && cycle == 0)
1455 cycle = sc->sc_chi_bpf;
1456
1457 if (basepipe == pipe)
1458 prevpipe = nextpipe = pipe;
1459 else {
1460 if (basepipe == 16) {
1461 if (dir == PIPEinput) {
1462 prevpipe = sc->sc_chi_pipe_in;
1463 } else {
1464 prevpipe = sc->sc_chi_pipe_out;
1465 }
1466 } else
1467 prevpipe = basepipe;
1468
1469 nextpipe = sc->sc_pipe[prevpipe].next;
1470
1471 while (sc->sc_pipe[nextpipe].cycle < cycle &&
1472 sc->sc_pipe[nextpipe].next != basepipe) {
1473 prevpipe = nextpipe;
1474 nextpipe = sc->sc_pipe[nextpipe].next;
1475 }
1476 }
1477
1478 if (prevpipe == 16) {
1479 if (dir == PIPEinput) {
1480 sc->sc_chi_pipe_in = pipe;
1481 } else {
1482 sc->sc_chi_pipe_out = pipe;
1483 }
1484 } else
1485 sc->sc_pipe[prevpipe].next = pipe;
1486
1487 sc->sc_pipe[pipe].next = nextpipe;
1488 sc->sc_pipe[pipe].cycle = cycle;
1489 sc->sc_pipe[pipe].length = len;
1490
1491 cmd = dbri_command_lock(sc);
1492
1493 switch (dir) {
1494 case PIPEinput:
1495 val = DBRI_DTS_VI | DBRI_DTS_INS | DBRI_DTS_PRVIN(prevpipe);
1496 val |= pipe;
1497 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val);
1498 *(cmd++) = DBRI_TS_LEN(len) | DBRI_TS_CYCLE(cycle) |
1499 DBRI_TS_NEXT(nextpipe);
1500 *(cmd++) = 0;
1501 break;
1502 case PIPEoutput:
1503 val = DBRI_DTS_VO | DBRI_DTS_INS | DBRI_DTS_PRVOUT(prevpipe);
1504 val |= pipe;
1505 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val);
1506 *(cmd++) = 0;
1507 *(cmd++) = DBRI_TS_LEN(len) | DBRI_TS_CYCLE(cycle) |
1508 DBRI_TS_NEXT(nextpipe);
1509 break;
1510 default:
1511 DPRINTF("%s: should not have happened!\n",
1512 sc->sc_dev.dv_xname);
1513 break;
1514 }
1515
1516 dbri_command_send(sc, cmd);
1517
1518 return;
1519 }
1520
1521 static int
1522 pipe_active(struct dbri_softc *sc, int pipe)
1523 {
1524
1525 return (sc->sc_pipe[pipe].desc != -1);
1526 }
1527
1528 /*
1529 * subroutines required to interface with audio(9)
1530 */
1531
1532 static int
1533 dbri_query_encoding(void *hdl, struct audio_encoding *ae)
1534 {
1535
1536 switch (ae->index) {
1537 case 0:
1538 strcpy(ae->name, AudioEulinear);
1539 ae->encoding = AUDIO_ENCODING_ULINEAR;
1540 ae->precision = 8;
1541 ae->flags = 0;
1542 break;
1543 case 1:
1544 strcpy(ae->name, AudioEmulaw);
1545 ae->encoding = AUDIO_ENCODING_ULAW;
1546 ae->precision = 8;
1547 ae->flags = 0;
1548 break;
1549 case 2:
1550 strcpy(ae->name, AudioEalaw);
1551 ae->encoding = AUDIO_ENCODING_ALAW;
1552 ae->precision = 8;
1553 ae->flags = 0;
1554 break;
1555 case 3:
1556 strcpy(ae->name, AudioEslinear);
1557 ae->encoding = AUDIO_ENCODING_SLINEAR;
1558 ae->precision = 8;
1559 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
1560 break;
1561 case 4:
1562 strcpy(ae->name, AudioEslinear_le);
1563 ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
1564 ae->precision = 16;
1565 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
1566 break;
1567 case 5:
1568 strcpy(ae->name, AudioEulinear_le);
1569 ae->encoding = AUDIO_ENCODING_ULINEAR_LE;
1570 ae->precision = 16;
1571 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
1572 break;
1573 case 6:
1574 strcpy(ae->name, AudioEslinear_be);
1575 ae->encoding = AUDIO_ENCODING_SLINEAR_BE;
1576 ae->precision = 16;
1577 ae->flags = 0;
1578 break;
1579 case 7:
1580 strcpy(ae->name, AudioEulinear_be);
1581 ae->encoding = AUDIO_ENCODING_ULINEAR_BE;
1582 ae->precision = 16;
1583 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
1584 break;
1585 case 8:
1586 strcpy(ae->name, AudioEslinear);
1587 ae->encoding = AUDIO_ENCODING_SLINEAR;
1588 ae->precision = 16;
1589 ae->flags = 0;
1590 break;
1591 default:
1592 return (EINVAL);
1593 }
1594
1595 return (0);
1596 }
1597
1598 static int
1599 dbri_set_params(void *hdl, int setmode, int usemode,
1600 struct audio_params *play, struct audio_params *rec,
1601 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
1602 {
1603 struct dbri_softc *sc = hdl;
1604 int rate;
1605 audio_params_t *p = NULL;
1606 stream_filter_list_t *fil;
1607 int mode;
1608
1609 /*
1610 * This device only has one clock, so make the sample rates match.
1611 */
1612 if (play->sample_rate != rec->sample_rate &&
1613 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
1614 if (setmode == AUMODE_PLAY) {
1615 rec->sample_rate = play->sample_rate;
1616 setmode |= AUMODE_RECORD;
1617 } else if (setmode == AUMODE_RECORD) {
1618 play->sample_rate = rec->sample_rate;
1619 setmode |= AUMODE_PLAY;
1620 } else
1621 return EINVAL;
1622 }
1623
1624 for (mode = AUMODE_RECORD; mode != -1;
1625 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
1626 if ((setmode & mode) == 0)
1627 continue;
1628
1629 p = mode == AUMODE_PLAY ? play : rec;
1630 if (p->sample_rate < 4000 || p->sample_rate > 50000) {
1631 DPRINTF("dbri_set_params: invalid rate %d\n",
1632 p->sample_rate);
1633 return EINVAL;
1634 }
1635
1636 fil = mode == AUMODE_PLAY ? pfil : rfil;
1637 DPRINTF("requested enc: %d rate: %d prec: %d chan: %d\n", p->encoding,
1638 p->sample_rate, p->precision, p->channels);
1639 if (auconv_set_converter(dbri_formats, DBRI_NFORMATS,
1640 mode, p, true, fil) < 0) {
1641 aprint_error("dbri_set_params: auconv_set_converter failed\n");
1642 return EINVAL;
1643 }
1644 if (fil->req_size > 0)
1645 p = &fil->filters[0].param;
1646 }
1647
1648 if (p == NULL) {
1649 DPRINTF("dbri_set_params: no parameters to set\n");
1650 return 0;
1651 }
1652
1653 DPRINTF("native enc: %d rate: %d prec: %d chan: %d\n", p->encoding,
1654 p->sample_rate, p->precision, p->channels);
1655
1656 for (rate = 0; CS4215_FREQ[rate].freq; rate++)
1657 if (CS4215_FREQ[rate].freq == p->sample_rate)
1658 break;
1659
1660 if (CS4215_FREQ[rate].freq == 0)
1661 return (EINVAL);
1662
1663 /* set frequency */
1664 sc->sc_mm.c.bcontrol[1] &= ~0x38;
1665 sc->sc_mm.c.bcontrol[1] |= CS4215_FREQ[rate].csval;
1666 sc->sc_mm.c.bcontrol[2] &= ~0x70;
1667 sc->sc_mm.c.bcontrol[2] |= CS4215_FREQ[rate].xtal;
1668
1669 switch (p->encoding) {
1670 case AUDIO_ENCODING_ULAW:
1671 sc->sc_mm.c.bcontrol[1] &= ~3;
1672 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_ULAW;
1673 break;
1674 case AUDIO_ENCODING_ALAW:
1675 sc->sc_mm.c.bcontrol[1] &= ~3;
1676 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_ALAW;
1677 break;
1678 case AUDIO_ENCODING_ULINEAR:
1679 sc->sc_mm.c.bcontrol[1] &= ~3;
1680 if (p->precision == 8) {
1681 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR8;
1682 } else {
1683 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR16;
1684 }
1685 break;
1686 case AUDIO_ENCODING_SLINEAR_BE:
1687 case AUDIO_ENCODING_SLINEAR:
1688 sc->sc_mm.c.bcontrol[1] &= ~3;
1689 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR16;
1690 break;
1691 }
1692
1693 switch (p->channels) {
1694 case 1:
1695 sc->sc_mm.c.bcontrol[1] &= ~CS4215_DFR_STEREO;
1696 break;
1697 case 2:
1698 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_STEREO;
1699 break;
1700 }
1701
1702 return (0);
1703 }
1704
1705 static int
1706 dbri_round_blocksize(void *hdl, int bs, int mode,
1707 const audio_params_t *param)
1708 {
1709
1710 /* DBRI DMA segment size, rounded down to 32bit alignment */
1711 return 0x1ffc;
1712 }
1713
1714 static int
1715 dbri_halt_output(void *hdl)
1716 {
1717 struct dbri_softc *sc = hdl;
1718
1719 if (!sc->sc_playing)
1720 return 0;
1721
1722 sc->sc_playing = 0;
1723 pipe_reset(sc, 4);
1724 return (0);
1725 }
1726
1727 static int
1728 dbri_getdev(void *hdl, struct audio_device *ret)
1729 {
1730
1731 *ret = dbri_device;
1732 return (0);
1733 }
1734
1735 static int
1736 dbri_set_port(void *hdl, mixer_ctrl_t *mc)
1737 {
1738 struct dbri_softc *sc = hdl;
1739 int latt = sc->sc_latt, ratt = sc->sc_ratt;
1740
1741 switch (mc->dev) {
1742 case DBRI_VOL_OUTPUT: /* master volume */
1743 latt = (latt & 0xc0) | (63 -
1744 min(mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] >> 2, 63));
1745 ratt = (ratt & 0xc0) | (63 -
1746 min(mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] >> 2, 63));
1747 break;
1748 case DBRI_ENABLE_MONO: /* built-in speaker */
1749 if (mc->un.ord == 1) {
1750 ratt |= CS4215_SE;
1751 } else
1752 ratt &= ~CS4215_SE;
1753 break;
1754 case DBRI_ENABLE_HEADPHONE: /* headphones output */
1755 if (mc->un.ord == 1) {
1756 latt |= CS4215_HE;
1757 } else
1758 latt &= ~CS4215_HE;
1759 break;
1760 case DBRI_ENABLE_LINE: /* line out */
1761 if (mc->un.ord == 1) {
1762 latt |= CS4215_LE;
1763 } else
1764 latt &= ~CS4215_LE;
1765 break;
1766 case DBRI_VOL_MONITOR:
1767 if (mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] ==
1768 sc->sc_monitor)
1769 return 0;
1770 sc->sc_monitor = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1771 break;
1772 case DBRI_INPUT_GAIN:
1773 sc->sc_linp = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1774 sc->sc_rinp = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1775 break;
1776 case DBRI_INPUT_SELECT:
1777 if (mc->un.mask == sc->sc_input)
1778 return 0;
1779 sc->sc_input = mc->un.mask;
1780 break;
1781 }
1782
1783 sc->sc_latt = latt;
1784 sc->sc_ratt = ratt;
1785
1786 mmcodec_setgain(sc, 0);
1787
1788 return (0);
1789 }
1790
1791 static int
1792 dbri_get_port(void *hdl, mixer_ctrl_t *mc)
1793 {
1794 struct dbri_softc *sc = hdl;
1795
1796 switch (mc->dev) {
1797 case DBRI_VOL_OUTPUT: /* master volume */
1798 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1799 (63 - (sc->sc_latt & 0x3f)) << 2;
1800 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1801 (63 - (sc->sc_ratt & 0x3f)) << 2;
1802 return (0);
1803 case DBRI_ENABLE_MONO: /* built-in speaker */
1804 mc->un.ord = (sc->sc_ratt & CS4215_SE) ? 1 : 0;
1805 return 0;
1806 case DBRI_ENABLE_HEADPHONE: /* headphones output */
1807 mc->un.ord = (sc->sc_latt & CS4215_HE) ? 1 : 0;
1808 return 0;
1809 case DBRI_ENABLE_LINE: /* line out */
1810 mc->un.ord = (sc->sc_latt & CS4215_LE) ? 1 : 0;
1811 return 0;
1812 case DBRI_VOL_MONITOR:
1813 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = sc->sc_monitor;
1814 return 0;
1815 case DBRI_INPUT_GAIN:
1816 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = sc->sc_linp;
1817 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = sc->sc_rinp;
1818 return 0;
1819 case DBRI_INPUT_SELECT:
1820 mc->un.mask = sc->sc_input;
1821 return 0;
1822 }
1823 return (EINVAL);
1824 }
1825
1826 static int
1827 dbri_query_devinfo(void *hdl, mixer_devinfo_t *di)
1828 {
1829
1830 switch (di->index) {
1831 case DBRI_MONITOR_CLASS:
1832 di->mixer_class = DBRI_MONITOR_CLASS;
1833 strcpy(di->label.name, AudioCmonitor);
1834 di->type = AUDIO_MIXER_CLASS;
1835 di->next = di->prev = AUDIO_MIXER_LAST;
1836 return 0;
1837 case DBRI_OUTPUT_CLASS:
1838 di->mixer_class = DBRI_OUTPUT_CLASS;
1839 strcpy(di->label.name, AudioCoutputs);
1840 di->type = AUDIO_MIXER_CLASS;
1841 di->next = di->prev = AUDIO_MIXER_LAST;
1842 return 0;
1843 case DBRI_INPUT_CLASS:
1844 di->mixer_class = DBRI_INPUT_CLASS;
1845 strcpy(di->label.name, AudioCinputs);
1846 di->type = AUDIO_MIXER_CLASS;
1847 di->next = di->prev = AUDIO_MIXER_LAST;
1848 return 0;
1849 case DBRI_VOL_OUTPUT: /* master volume */
1850 di->mixer_class = DBRI_OUTPUT_CLASS;
1851 di->next = di->prev = AUDIO_MIXER_LAST;
1852 strcpy(di->label.name, AudioNmaster);
1853 di->type = AUDIO_MIXER_VALUE;
1854 di->un.v.num_channels = 2;
1855 strcpy(di->un.v.units.name, AudioNvolume);
1856 return (0);
1857 case DBRI_INPUT_GAIN: /* input gain */
1858 di->mixer_class = DBRI_INPUT_CLASS;
1859 di->next = di->prev = AUDIO_MIXER_LAST;
1860 strcpy(di->label.name, AudioNrecord);
1861 di->type = AUDIO_MIXER_VALUE;
1862 di->un.v.num_channels = 2;
1863 strcpy(di->un.v.units.name, AudioNvolume);
1864 return (0);
1865 case DBRI_VOL_MONITOR: /* monitor volume */
1866 di->mixer_class = DBRI_MONITOR_CLASS;
1867 di->next = di->prev = AUDIO_MIXER_LAST;
1868 strcpy(di->label.name, AudioNmonitor);
1869 di->type = AUDIO_MIXER_VALUE;
1870 di->un.v.num_channels = 1;
1871 strcpy(di->un.v.units.name, AudioNvolume);
1872 return (0);
1873 case DBRI_ENABLE_MONO: /* built-in speaker */
1874 di->mixer_class = DBRI_OUTPUT_CLASS;
1875 di->next = di->prev = AUDIO_MIXER_LAST;
1876 strcpy(di->label.name, AudioNmono);
1877 di->type = AUDIO_MIXER_ENUM;
1878 di->un.e.num_mem = 2;
1879 strcpy(di->un.e.member[0].label.name, AudioNoff);
1880 di->un.e.member[0].ord = 0;
1881 strcpy(di->un.e.member[1].label.name, AudioNon);
1882 di->un.e.member[1].ord = 1;
1883 return (0);
1884 case DBRI_ENABLE_HEADPHONE: /* headphones output */
1885 di->mixer_class = DBRI_OUTPUT_CLASS;
1886 di->next = di->prev = AUDIO_MIXER_LAST;
1887 strcpy(di->label.name, AudioNheadphone);
1888 di->type = AUDIO_MIXER_ENUM;
1889 di->un.e.num_mem = 2;
1890 strcpy(di->un.e.member[0].label.name, AudioNoff);
1891 di->un.e.member[0].ord = 0;
1892 strcpy(di->un.e.member[1].label.name, AudioNon);
1893 di->un.e.member[1].ord = 1;
1894 return (0);
1895 case DBRI_ENABLE_LINE: /* line out */
1896 di->mixer_class = DBRI_OUTPUT_CLASS;
1897 di->next = di->prev = AUDIO_MIXER_LAST;
1898 strcpy(di->label.name, AudioNline);
1899 di->type = AUDIO_MIXER_ENUM;
1900 di->un.e.num_mem = 2;
1901 strcpy(di->un.e.member[0].label.name, AudioNoff);
1902 di->un.e.member[0].ord = 0;
1903 strcpy(di->un.e.member[1].label.name, AudioNon);
1904 di->un.e.member[1].ord = 1;
1905 return (0);
1906 case DBRI_INPUT_SELECT:
1907 di->mixer_class = DBRI_INPUT_CLASS;
1908 strcpy(di->label.name, AudioNsource);
1909 di->type = AUDIO_MIXER_SET;
1910 di->prev = di->next = AUDIO_MIXER_LAST;
1911 di->un.s.num_mem = 2;
1912 strcpy(di->un.s.member[0].label.name, AudioNline);
1913 di->un.s.member[0].mask = 1 << 0;
1914 strcpy(di->un.s.member[1].label.name, AudioNmicrophone);
1915 di->un.s.member[1].mask = 1 << 1;
1916 return 0;
1917 }
1918
1919 return (ENXIO);
1920 }
1921
1922 static size_t
1923 dbri_round_buffersize(void *hdl, int dir, size_t bufsize)
1924 {
1925 #ifdef DBRI_BIG_BUFFER
1926 return 16*0x1ffc; /* use ~128KB buffer */
1927 #else
1928 return bufsize;
1929 #endif
1930 }
1931
1932 static int
1933 dbri_get_props(void *hdl)
1934 {
1935
1936 return AUDIO_PROP_MMAP | AUDIO_PROP_FULLDUPLEX;
1937 }
1938
1939 static int
1940 dbri_trigger_output(void *hdl, void *start, void *end, int blksize,
1941 void (*intr)(void *), void *intrarg,
1942 const struct audio_params *param)
1943 {
1944 struct dbri_softc *sc = hdl;
1945 unsigned long count, num;
1946
1947 if (sc->sc_playing)
1948 return 0;
1949
1950 count = (unsigned long)(((char *)end - (char *)start));
1951 num = count / blksize;
1952
1953 DPRINTF("trigger_output(%lx %lx) : %d %ld %ld\n",
1954 (unsigned long)intr,
1955 (unsigned long)intrarg, blksize, count, num);
1956
1957 sc->sc_params = *param;
1958
1959 if (sc->sc_recording == 0) {
1960 /* do not muck with the codec when it's already in use */
1961 mmcodec_setcontrol(sc);
1962 mmcodec_init_data(sc);
1963 }
1964
1965 /*
1966 * always use DMA descriptor 0 for output
1967 * no need to allocate them dynamically since we only ever have
1968 * exactly one input stream and exactly one output stream
1969 */
1970 setup_ring_xmit(sc, 4, 0, num, blksize, intr, intrarg);
1971 sc->sc_playing = 1;
1972 return 0;
1973 }
1974
1975 static int
1976 dbri_halt_input(void *cookie)
1977 {
1978 struct dbri_softc *sc = cookie;
1979
1980 if (!sc->sc_recording)
1981 return 0;
1982
1983 sc->sc_recording = 0;
1984 pipe_reset(sc, 6);
1985 return 0;
1986 }
1987
1988 static int
1989 dbri_trigger_input(void *hdl, void *start, void *end, int blksize,
1990 void (*intr)(void *), void *intrarg,
1991 const struct audio_params *param)
1992 {
1993 struct dbri_softc *sc = hdl;
1994 unsigned long count, num;
1995
1996 if (sc->sc_recording)
1997 return 0;
1998
1999 count = (unsigned long)(((char *)end - (char *)start));
2000 num = count / blksize;
2001
2002 DPRINTF("trigger_input(%lx %lx) : %d %ld %ld\n",
2003 (unsigned long)intr,
2004 (unsigned long)intrarg, blksize, count, num);
2005
2006 sc->sc_params = *param;
2007
2008 if (sc->sc_playing == 0) {
2009
2010 /*
2011 * we don't support different parameters for playing and
2012 * recording anyway so don't bother whacking the codec if
2013 * it's already set up
2014 */
2015 mmcodec_setcontrol(sc);
2016 mmcodec_init_data(sc);
2017 }
2018
2019 sc->sc_recording = 1;
2020 setup_ring_recv(sc, 6, 1, num, blksize, intr, intrarg);
2021 return 0;
2022 }
2023
2024
2025 static u_int32_t
2026 reverse_bytes(u_int32_t b, int len)
2027 {
2028 switch (len) {
2029 case 32:
2030 b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16);
2031 case 16:
2032 b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8);
2033 case 8:
2034 b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4);
2035 case 4:
2036 b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2);
2037 case 2:
2038 b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1);
2039 case 1:
2040 case 0:
2041 break;
2042 default:
2043 DPRINTF("reverse_bytes: unsupported length\n");
2044 };
2045
2046 return (b);
2047 }
2048
2049 static void *
2050 dbri_malloc(void *v, int dir, size_t s, struct malloc_type *mt, int flags)
2051 {
2052 struct dbri_softc *sc = v;
2053 struct dbri_desc *dd = &sc->sc_desc[sc->sc_desc_used];
2054 int rseg;
2055
2056 if (bus_dmamap_create(sc->sc_dmat, s, 1, s, 0, BUS_DMA_NOWAIT,
2057 &dd->dmamap) == 0) {
2058 if (bus_dmamem_alloc(sc->sc_dmat, s, 0, 0, &dd->dmaseg,
2059 1, &rseg, BUS_DMA_NOWAIT) == 0) {
2060 if (bus_dmamem_map(sc->sc_dmat, &dd->dmaseg, rseg, s,
2061 &dd->buf, BUS_DMA_NOWAIT|BUS_DMA_COHERENT) == 0) {
2062 if (dd->buf != NULL) {
2063 if (bus_dmamap_load(sc->sc_dmat,
2064 dd->dmamap, dd->buf, s, NULL,
2065 BUS_DMA_NOWAIT) == 0) {
2066 dd->len = s;
2067 dd->busy = 0;
2068 dd->callback = NULL;
2069 dd->dmabase =
2070 dd->dmamap->dm_segs[0].ds_addr;
2071 DPRINTF("dbri_malloc: using buffer %d %08x\n",
2072 sc->sc_desc_used, (uint32_t)dd->buf);
2073 sc->sc_desc_used++;
2074 return dd->buf;
2075 } else
2076 aprint_error("dbri_malloc: load failed\n");
2077 } else
2078 aprint_error("dbri_malloc: map returned NULL\n");
2079 } else
2080 aprint_error("dbri_malloc: map failed\n");
2081 bus_dmamem_free(sc->sc_dmat, &dd->dmaseg, rseg);
2082 } else
2083 aprint_error("dbri_malloc: malloc() failed\n");
2084 bus_dmamap_destroy(sc->sc_dmat, dd->dmamap);
2085 } else
2086 aprint_error("dbri_malloc: bus_dmamap_create() failed\n");
2087 return NULL;
2088 }
2089
2090 static void
2091 dbri_free(void *v, void *p, struct malloc_type *mt)
2092 {
2093 free(p, mt);
2094 }
2095
2096 static paddr_t
2097 dbri_mappage(void *v, void *mem, off_t off, int prot)
2098 {
2099 struct dbri_softc *sc = v;;
2100 int current;
2101
2102 if (off < 0)
2103 return -1;
2104
2105 current = 0;
2106 while ((current < sc->sc_desc_used) &&
2107 (sc->sc_desc[current].buf != mem))
2108 current++;
2109
2110 if (current < sc->sc_desc_used) {
2111 return bus_dmamem_mmap(sc->sc_dmat,
2112 &sc->sc_desc[current].dmaseg, 1, off, prot, BUS_DMA_WAITOK);
2113 }
2114
2115 return -1;
2116 }
2117
2118 static int
2119 dbri_open(void *cookie, int flags)
2120 {
2121 struct dbri_softc *sc = cookie;
2122
2123 DPRINTF("%s: %d\n", __func__, sc->sc_refcount);
2124
2125 if (sc->sc_refcount == 0)
2126 dbri_bring_up(sc);
2127
2128 sc->sc_refcount++;
2129
2130 return 0;
2131 }
2132
2133 static void
2134 dbri_close(void *cookie)
2135 {
2136 struct dbri_softc *sc = cookie;
2137
2138 DPRINTF("%s: %d\n", __func__, sc->sc_refcount);
2139
2140 sc->sc_refcount--;
2141 KASSERT(sc->sc_refcount >= 0);
2142 if (sc->sc_refcount > 0)
2143 return;
2144
2145 dbri_set_power(sc, 0);
2146 sc->sc_playing = 0;
2147 sc->sc_recording = 0;
2148 }
2149
2150 static void
2151 dbri_powerhook(int why, void *cookie)
2152 {
2153 struct dbri_softc *sc = cookie;
2154
2155 if (why == sc->sc_pmgrstate)
2156 return;
2157
2158 switch(why)
2159 {
2160 case PWR_SUSPEND:
2161 dbri_set_power(sc, 0);
2162 break;
2163 case PWR_RESUME:
2164 if (sc->sc_powerstate != 0)
2165 break;
2166 aprint_verbose("resume: %d\n", sc->sc_refcount);
2167 sc->sc_pmgrstate = PWR_RESUME;
2168 dbri_bring_up(sc);
2169 if (sc->sc_playing) {
2170 volatile u_int32_t *cmd;
2171 int s;
2172
2173 dbri_bring_up(sc);
2174 s = splaudio();
2175 cmd = dbri_command_lock(sc);
2176 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP,
2177 0, sc->sc_pipe[4].sdp |
2178 DBRI_SDP_VALID_POINTER |
2179 DBRI_SDP_EVERY | DBRI_SDP_CLEAR);
2180 *(cmd++) = sc->sc_dmabase +
2181 dbri_dma_off(xmit, 0);
2182 dbri_command_send(sc, cmd);
2183 splx(s);
2184 }
2185 break;
2186 default:
2187 return;
2188 }
2189 sc->sc_pmgrstate = why;
2190 }
2191
2192 #endif /* NAUDIO > 0 */
2193