1 /* $NetBSD: dbri.c,v 1.26 2010/01/02 01:43:42 christos Exp $ */
4 * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
5 * Copyright (c) 1998, 1999 Brent Baccala (baccala@freesoft.org)
6 * Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill@netbsd.org>
7 * Copyright (c) 2005 Michael Lorenz <macallan@netbsd.org>
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.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
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.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: dbri.c,v 1.26 2010/01/02 01:43:42 christos Exp $");
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/errno.h>
45 #include <sys/device.h>
46 #include <sys/malloc.h>
48 #include <sys/kernel.h>
52 #include <dev/sbus/sbusvar.h>
53 #include <sparc/sparc/auxreg.h>
54 #include <machine/autoconf.h>
56 #include <sys/audioio.h>
57 #include <dev/audio_if.h>
58 #include <dev/auconv.h>
60 #include <dev/ic/cs4215reg.h>
61 #include <dev/ic/cs4215var.h>
62 #include <dev/sbus/dbrireg.h>
63 #include <dev/sbus/dbrivar.h>
65 #include "opt_sbus_dbri.h"
67 #define DBRI_ROM_NAME_PREFIX "SUNW,DBRI"
70 # define DPRINTF aprint_normal
72 # define DPRINTF while (0) printf
75 static const char *dbri_supported
[] = {
96 static void dbri_attach_sbus(device_t
, device_t
, void *);
97 static int dbri_match_sbus(device_t
, cfdata_t
, void *);
99 static void dbri_config_interrupts(device_t
);
101 /* interrupt handler */
102 static int dbri_intr(void *);
103 static void dbri_softint(void *);
105 /* supporting subroutines */
106 static int dbri_init(struct dbri_softc
*);
107 static int dbri_reset(struct dbri_softc
*);
108 static volatile uint32_t *dbri_command_lock(struct dbri_softc
*);
109 static void dbri_command_send(struct dbri_softc
*, volatile uint32_t *);
110 static void dbri_process_interrupt_buffer(struct dbri_softc
*);
111 static void dbri_process_interrupt(struct dbri_softc
*, int32_t);
113 /* mmcodec subroutines */
114 static int mmcodec_init(struct dbri_softc
*);
115 static void mmcodec_init_data(struct dbri_softc
*);
116 static void mmcodec_pipe_init(struct dbri_softc
*);
117 static void mmcodec_default(struct dbri_softc
*);
118 static void mmcodec_setgain(struct dbri_softc
*, int);
119 static int mmcodec_setcontrol(struct dbri_softc
*);
121 /* chi subroutines */
122 static void chi_reset(struct dbri_softc
*, enum ms
, int);
124 /* pipe subroutines */
125 static void pipe_setup(struct dbri_softc
*, int, int);
126 static void pipe_reset(struct dbri_softc
*, int);
127 static void pipe_receive_fixed(struct dbri_softc
*, int,
128 volatile uint32_t *);
129 static void pipe_transmit_fixed(struct dbri_softc
*, int, uint32_t);
131 static void pipe_ts_link(struct dbri_softc
*, int, enum io
, int, int, int);
132 static int pipe_active(struct dbri_softc
*, int);
135 static int dbri_query_encoding(void *, struct audio_encoding
*);
136 static int dbri_set_params(void *, int, int, struct audio_params
*,
137 struct audio_params
*,stream_filter_list_t
*, stream_filter_list_t
*);
138 static int dbri_round_blocksize(void *, int, int, const audio_params_t
*);
139 static int dbri_halt_output(void *);
140 static int dbri_halt_input(void *);
141 static int dbri_getdev(void *, struct audio_device
*);
142 static int dbri_set_port(void *, mixer_ctrl_t
*);
143 static int dbri_get_port(void *, mixer_ctrl_t
*);
144 static int dbri_query_devinfo(void *, mixer_devinfo_t
*);
145 static size_t dbri_round_buffersize(void *, int, size_t);
146 static int dbri_get_props(void *);
147 static int dbri_open(void *, int);
148 static void dbri_close(void *);
150 static void setup_ring_xmit(struct dbri_softc
*, int, int, int, int,
151 void (*)(void *), void *);
152 static void setup_ring_recv(struct dbri_softc
*, int, int, int, int,
153 void (*)(void *), void *);
155 static int dbri_trigger_output(void *, void *, void *, int,
156 void (*)(void *), void *, const struct audio_params
*);
157 static int dbri_trigger_input(void *, void *, void *, int,
158 void (*)(void *), void *, const struct audio_params
*);
160 static void *dbri_malloc(void *, int, size_t, struct malloc_type
*, int);
161 static void dbri_free(void *, void *, struct malloc_type
*);
162 static paddr_t
dbri_mappage(void *, void *, off_t
, int);
163 static void dbri_set_power(struct dbri_softc
*, int);
164 static void dbri_bring_up(struct dbri_softc
*);
165 static bool dbri_suspend(device_t PMF_FN_PROTO
);
166 static bool dbri_resume(device_t PMF_FN_PROTO
);
168 /* stupid support routines */
169 static uint32_t reverse_bytes(uint32_t, int);
171 struct audio_device dbri_device
= {
177 struct audio_hw_if dbri_hw_if
= {
183 dbri_round_blocksize
,
184 NULL
, /* commit_settings */
185 NULL
, /* init_output */
186 NULL
, /* init_input */
187 NULL
, /* start_output */
188 NULL
, /* start_input */
191 NULL
, /* speaker_ctl */
199 dbri_round_buffersize
,
206 CFATTACH_DECL_NEW(dbri
, sizeof(struct dbri_softc
),
207 dbri_match_sbus
, dbri_attach_sbus
, NULL
, NULL
);
209 #define DBRI_NFORMATS 4
210 static const struct audio_format dbri_formats
[DBRI_NFORMATS
] = {
211 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_SLINEAR_BE
, 16, 16,
212 2, AUFMT_STEREO
, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
214 /* {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULAW, 8, 8,
215 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
217 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ALAW, 8, 8,
218 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
220 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR, 8, 8,
221 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
223 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ULAW
, 8, 8,
224 1, AUFMT_MONAURAL
, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
226 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ALAW
, 8, 8,
227 1, AUFMT_MONAURAL
, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
229 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ULINEAR
, 8, 8,
230 1, AUFMT_MONAURAL
, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100,
238 DBRI_ENABLE_HEADPHONE
,
250 * Autoconfig routines
253 dbri_match_sbus(device_t parent
, cfdata_t match
, void *aux
)
255 struct sbus_attach_args
*sa
= aux
;
259 if (strncmp(DBRI_ROM_NAME_PREFIX
, sa
->sa_name
, 9))
262 ver
= &sa
->sa_name
[9];
264 for (i
= 0; dbri_supported
[i
][0] != '\0'; i
++)
265 if (strcmp(dbri_supported
[i
], ver
) == 0)
272 dbri_attach_sbus(device_t parent
, device_t self
, void *aux
)
274 struct dbri_softc
*sc
= device_private(self
);
275 struct sbus_attach_args
*sa
= aux
;
276 bus_space_handle_t ioh
;
278 int error
, rseg
, pwr
, i
;
279 char *ver
= &sa
->sa_name
[9];
282 sc
->sc_iot
= sa
->sa_bustag
;
283 sc
->sc_dmat
= sa
->sa_dmatag
;
284 sc
->sc_powerstate
= 1;
286 pwr
= prom_getpropint(sa
->sa_node
,"pwr-on-auxio",0);
287 aprint_normal(": rev %s\n", ver
);
291 * we can control DBRI power via auxio and we're initially
295 sc
->sc_have_powerctl
= 1;
296 sc
->sc_powerstate
= 0;
297 dbri_set_power(sc
, 1);
298 if (!pmf_device_register(self
, dbri_suspend
, dbri_resume
)) {
299 aprint_error_dev(self
,
300 "cannot set power mgmt handler\n");
303 /* we can't control power so we're always up */
304 sc
->sc_have_powerctl
= 0;
305 sc
->sc_powerstate
= 1;
308 for (i
= 0; i
< DBRI_NUM_DESCRIPTORS
; i
++) {
309 sc
->sc_desc
[i
].softint
= softint_establish(SOFTINT_SERIAL
,
310 dbri_softint
, &sc
->sc_desc
[i
]);
313 if (sa
->sa_npromvaddrs
)
314 ioh
= (bus_space_handle_t
)sa
->sa_promvaddrs
[0];
316 if (sbus_bus_map(sa
->sa_bustag
, sa
->sa_slot
,
317 sa
->sa_offset
, sa
->sa_size
,
318 BUS_SPACE_MAP_LINEAR
, /*0,*/ &ioh
) != 0) {
319 aprint_error("%s @ sbus: cannot map registers\n",
327 size
= sizeof(struct dbri_dma
);
329 /* get a DMA handle */
330 if ((error
= bus_dmamap_create(sc
->sc_dmat
, size
, 1, size
, 0,
331 BUS_DMA_NOWAIT
, &sc
->sc_dmamap
)) != 0) {
332 aprint_error_dev(self
, "DMA map create error %d\n",
337 /* allocate DMA buffer */
338 if ((error
= bus_dmamem_alloc(sc
->sc_dmat
, size
, 0, 0, &sc
->sc_dmaseg
,
339 1, &rseg
, BUS_DMA_NOWAIT
)) != 0) {
340 aprint_error_dev(self
, "DMA buffer alloc error %d\n",
345 /* map DMA buffer into CPU addressable space */
346 if ((error
= bus_dmamem_map(sc
->sc_dmat
, &sc
->sc_dmaseg
, rseg
, size
,
348 BUS_DMA_NOWAIT
|BUS_DMA_COHERENT
)) != 0) {
349 aprint_error_dev(self
, "DMA buffer map error %d\n",
354 /* load the buffer */
355 if ((error
= bus_dmamap_load(sc
->sc_dmat
, sc
->sc_dmamap
,
356 sc
->sc_membase
, size
, NULL
,
357 BUS_DMA_NOWAIT
)) != 0) {
358 aprint_error_dev(self
, "DMA buffer map load error %d\n",
360 bus_dmamem_unmap(sc
->sc_dmat
, sc
->sc_membase
, size
);
361 bus_dmamem_free(sc
->sc_dmat
, &sc
->sc_dmaseg
, rseg
);
365 /* map the registers into memory */
367 /* kernel virtual address of DMA buffer */
368 sc
->sc_dma
= (struct dbri_dma
*)sc
->sc_membase
;
369 /* physical address of DMA buffer */
370 sc
->sc_dmabase
= sc
->sc_dmamap
->dm_segs
[0].ds_addr
;
371 sc
->sc_bufsiz
= size
;
373 bus_intr_establish(sa
->sa_bustag
, sa
->sa_pri
, IPL_SCHED
, dbri_intr
,
377 sc
->sc_desc_used
= 0;
380 sc
->sc_recording
= 0;
381 config_interrupts(self
, &dbri_config_interrupts
);
387 * lowlevel routine to switch power for the DBRI chip
390 dbri_set_power(struct dbri_softc
*sc
, int state
)
394 if (sc
->sc_have_powerctl
== 0)
396 if (sc
->sc_powerstate
== state
)
400 DPRINTF("%s: waiting to power up... ",
401 device_xname(sc
->sc_dev
));
403 *AUXIO4M_REG
|= (AUXIO4M_MMX
);
406 DPRINTF("done (%02x)\n", *AUXIO4M_REG
);
408 DPRINTF("%s: powering down\n", device_xname(sc
->sc_dev
));
410 *AUXIO4M_REG
&= ~AUXIO4M_MMX
;
412 DPRINTF("done (%02x})\n", *AUXIO4M_REG
);
414 sc
->sc_powerstate
= state
;
418 * power up and re-initialize the chip
421 dbri_bring_up(struct dbri_softc
*sc
)
424 if (sc
->sc_have_powerctl
== 0)
427 if (sc
->sc_powerstate
== 1)
430 /* ok, we really need to do something */
431 dbri_set_power(sc
, 1);
434 * re-initialize the chip but skip all the probing, don't overwrite
435 * any other settings either
438 mmcodec_setgain(sc
, 1);
439 mmcodec_pipe_init(sc
);
440 mmcodec_init_data(sc
);
441 mmcodec_setgain(sc
, 0);
445 dbri_config_interrupts(device_t dev
)
447 struct dbri_softc
*sc
= device_private(dev
);
452 /* Attach ourselves to the high level audio interface */
453 audio_attach_mi(&dbri_hw_if
, sc
, sc
->sc_dev
);
455 /* power down until open() */
456 dbri_set_power(sc
, 0);
463 struct dbri_softc
*sc
= hdl
;
464 bus_space_tag_t iot
= sc
->sc_iot
;
465 bus_space_handle_t ioh
= sc
->sc_ioh
;
468 /* clear interrupt */
469 x
= bus_space_read_4(iot
, ioh
, DBRI_REG1
);
470 if (x
& (DBRI_MRR
| DBRI_MLE
| DBRI_LBG
| DBRI_MBE
)) {
474 aprint_debug_dev(sc
->sc_dev
,
475 "multiple ack error on sbus\n");
477 aprint_debug_dev(sc
->sc_dev
,
478 "multiple late error on sbus\n");
480 aprint_debug_dev(sc
->sc_dev
,
481 "lost bus grant on sbus\n");
483 aprint_debug_dev(sc
->sc_dev
, "burst error on sbus\n");
486 * Some of these errors disable the chip's circuitry.
487 * Re-enable the circuitry and keep on going.
490 tmp
= bus_space_read_4(iot
, ioh
, DBRI_REG0
);
491 tmp
&= ~(DBRI_DISABLE_MASTER
);
492 bus_space_write_4(iot
, ioh
, DBRI_REG0
, tmp
);
496 if (!x
& 1) /* XXX: DBRI_INTR_REQ */
500 dbri_process_interrupt_buffer(sc
);
506 dbri_softint(void *cookie
)
508 struct dbri_desc
*dd
= cookie
;
510 if (dd
->callback
!= NULL
)
511 dd
->callback(dd
->callback_args
);
515 dbri_init(struct dbri_softc
*sc
)
517 bus_space_tag_t iot
= sc
->sc_iot
;
518 bus_space_handle_t ioh
= sc
->sc_ioh
;
520 volatile uint32_t *cmd
;
526 cmd
= dbri_command_lock(sc
);
528 /* XXX: Initialize interrupt ring buffer */
529 sc
->sc_dma
->intr
[0] = (uint32_t)sc
->sc_dmabase
+ dbri_dma_off(intr
, 0);
532 /* Initialize pipes */
533 for (n
= 0; n
< DBRI_PIPE_MAX
; n
++)
534 sc
->sc_pipe
[n
].desc
= sc
->sc_pipe
[n
].next
= -1;
536 for (n
= 1; n
< DBRI_INT_BLOCKS
; n
++) {
537 sc
->sc_dma
->intr
[n
] = 0;
540 /* Disable all SBus bursts */
541 /* XXX 16 byte bursts cause errors, the rest works */
542 reg
= bus_space_read_4(iot
, ioh
, DBRI_REG0
);
544 /*reg &= ~(DBRI_BURST_4 | DBRI_BURST_8 | DBRI_BURST_16);*/
545 reg
|= (DBRI_BURST_4
| DBRI_BURST_8
);
546 bus_space_write_4(iot
, ioh
, DBRI_REG0
, reg
);
548 /* setup interrupt queue */
549 dmaaddr
= (uint32_t)sc
->sc_dmabase
+ dbri_dma_off(intr
, 0);
550 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_IIQ
, 0, 0);
553 dbri_command_send(sc
, cmd
);
558 dbri_reset(struct dbri_softc
*sc
)
562 bus_space_tag_t iot
= sc
->sc_iot
;
563 bus_space_handle_t ioh
= sc
->sc_ioh
;
565 bus_space_write_4(iot
, ioh
, DBRI_REG0
, DBRI_SOFT_RESET
);
566 while ((bus_space_read_4(iot
, ioh
, DBRI_REG0
) & DBRI_SOFT_RESET
) &&
572 aprint_error_dev(sc
->sc_dev
, "reset timed out\n");
576 static volatile uint32_t *
577 dbri_command_lock(struct dbri_softc
*sc
)
581 aprint_debug_dev(sc
->sc_dev
, "command buffer locked\n");
585 return (&sc
->sc_dma
->command
[0]);
589 dbri_command_send(struct dbri_softc
*sc
, volatile uint32_t *cmd
)
591 bus_space_handle_t ioh
= sc
->sc_ioh
;
592 bus_space_tag_t iot
= sc
->sc_iot
;
593 int maxloops
= 1000000;
600 if (sc
->sc_locked
!= 0) {
601 aprint_error_dev(sc
->sc_dev
,
602 "command buffer improperly locked\n");
603 } else if ((cmd
- &sc
->sc_dma
->command
[0]) >= DBRI_NUM_COMMANDS
- 1) {
604 aprint_error_dev(sc
->sc_dev
, "command buffer overflow\n");
606 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_PAUSE
, 0, 0);
607 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_WAIT
, 1, 0);
609 bus_space_write_4(iot
, ioh
, DBRI_REG8
, sc
->sc_dmabase
);
610 while ((--maxloops
) > 0 &&
611 (bus_space_read_4(iot
, ioh
, DBRI_REG0
)
612 & DBRI_COMMAND_VALID
)) {
613 bus_space_barrier(iot
, ioh
, DBRI_REG0
, 4,
614 BUS_SPACE_BARRIER_READ
);
619 aprint_error_dev(sc
->sc_dev
,
620 "chip never completed command buffer\n");
623 DPRINTF("%s: command completed\n",
624 device_xname(sc
->sc_dev
));
626 while ((--maxloops
) > 0 && (!sc
->sc_waitseen
))
627 dbri_process_interrupt_buffer(sc
);
629 aprint_error_dev(sc
->sc_dev
, "chip never acked WAIT\n");
640 dbri_process_interrupt_buffer(struct dbri_softc
*sc
)
644 while ((i
= sc
->sc_dma
->intr
[sc
->sc_irqp
]) != 0) {
645 sc
->sc_dma
->intr
[sc
->sc_irqp
] = 0;
648 if (sc
->sc_irqp
== DBRI_INT_BLOCKS
)
650 else if ((sc
->sc_irqp
& (DBRI_INT_BLOCKS
- 1)) == 0)
653 dbri_process_interrupt(sc
, i
);
660 dbri_process_interrupt(struct dbri_softc
*sc
, int32_t i
)
663 const int liu_states
[] = { 1, 0, 8, 3, 4, 5, 6, 7 };
665 int val
= DBRI_INTR_GETVAL(i
);
666 int channel
= DBRI_INTR_GETCHAN(i
);
667 int command
= DBRI_INTR_GETCMD(i
);
668 int code
= DBRI_INTR_GETCODE(i
);
670 int rval
= DBRI_INTR_GETRVAL(i
);
672 if (channel
== DBRI_INTR_CMD
&& command
== DBRI_COMMAND_WAIT
)
676 case DBRI_INTR_XCMP
: /* transmission complete */
679 struct dbri_desc
*dd
;
681 td
= sc
->sc_pipe
[channel
].desc
;
682 dd
= &sc
->sc_desc
[td
];
684 if (dd
->callback
!= NULL
)
685 softint_schedule(dd
->softint
);
688 case DBRI_INTR_FXDT
: /* fixed data change */
689 DPRINTF("dbri_intr: Fixed data change (%d: %x)\n", channel
,
692 printf("reg: %08x\n", sc
->sc_mm
.status
);
694 if (sc
->sc_pipe
[channel
].sdp
& DBRI_SDP_MSB
)
695 val
= reverse_bytes(val
, sc
->sc_pipe
[channel
].length
);
696 if (sc
->sc_pipe
[channel
].prec
)
697 *(sc
->sc_pipe
[channel
].prec
) = val
;
699 DPRINTF("%s: wakeup %p\n", device_xname(sc
->sc_dev
), sc
);
704 DPRINTF("dbri_intr: SBRI\n");
709 struct dbri_desc
*dd
;
711 td
= sc
->sc_pipe
[channel
].desc
;
712 dd
= &sc
->sc_desc
[td
];
714 if (dd
->callback
!= NULL
)
715 softint_schedule(dd
->softint
);
720 volatile uint32_t *cmd
;
721 int td
= sc
->sc_pipe
[channel
].desc
;
723 DPRINTF("%s: DBRI_INTR_UNDR\n", device_xname(sc
->sc_dev
));
725 sc
->sc_dma
->xmit
[td
].status
= 0;
727 cmd
= dbri_command_lock(sc
);
728 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_SDP
, 0,
729 sc
->sc_pipe
[channel
].sdp
|
730 DBRI_SDP_VALID_POINTER
|
733 *(cmd
++) = sc
->sc_dmabase
+ dbri_dma_off(xmit
, td
);
734 dbri_command_send(sc
, cmd
);
742 aprint_error_dev(sc
->sc_dev
, "unknown interrupt code %d\n",
755 mmcodec_init(struct dbri_softc
*sc
)
757 bus_space_handle_t ioh
= sc
->sc_ioh
;
758 bus_space_tag_t iot
= sc
->sc_iot
;
762 reg2
= bus_space_read_4(iot
, ioh
, DBRI_REG2
);
763 DPRINTF("mmcodec_init: PIO reads %x\n", reg2
);
765 if (reg2
& DBRI_PIO2
) {
766 aprint_normal_dev(sc
->sc_dev
, " onboard CS4215 detected\n");
767 sc
->sc_mm
.onboard
= 1;
770 if (reg2
& DBRI_PIO0
) {
771 aprint_normal_dev(sc
->sc_dev
, "speakerbox detected\n");
772 bus_space_write_4(iot
, ioh
, DBRI_REG2
, DBRI_PIO2_ENABLE
);
773 sc
->sc_mm
.onboard
= 0;
776 if ((reg2
& DBRI_PIO2
) && (reg2
& DBRI_PIO0
)) {
777 aprint_normal_dev(sc
->sc_dev
, "using speakerbox\n");
778 bus_space_write_4(iot
, ioh
, DBRI_REG2
, DBRI_PIO2_ENABLE
);
779 sc
->sc_mm
.onboard
= 0;
782 if (!(reg2
& (DBRI_PIO0
|DBRI_PIO2
))) {
783 aprint_normal_dev(sc
->sc_dev
, "no mmcodec found\n");
787 sc
->sc_version
= 0xff;
789 mmcodec_pipe_init(sc
);
792 sc
->sc_mm
.offset
= sc
->sc_mm
.onboard
? 0 : 8;
795 * mmcodec_setcontrol() sometimes fails right after powerup
796 * so we just try again until we either get a useful response or run
800 while (mmcodec_setcontrol(sc
) == -1 || sc
->sc_version
== 0xff) {
804 DPRINTF("%s: cs4215 probe failed at offset %d\n",
805 device_xname(sc
->sc_dev
), sc
->sc_mm
.offset
);
811 aprint_normal_dev(sc
->sc_dev
, "cs4215 rev %c found at offset %d\n",
812 0x43 + (sc
->sc_version
& 0xf), sc
->sc_mm
.offset
);
814 /* set some sane defaults for mmcodec_init_data */
815 sc
->sc_params
.channels
= 2;
816 sc
->sc_params
.precision
= 16;
818 mmcodec_init_data(sc
);
824 mmcodec_init_data(struct dbri_softc
*sc
)
826 bus_space_tag_t iot
= sc
->sc_iot
;
827 bus_space_handle_t ioh
= sc
->sc_ioh
;
831 tmp
= bus_space_read_4(iot
, ioh
, DBRI_REG0
);
832 tmp
&= ~(DBRI_CHI_ACTIVATE
); /* disable CHI */
833 bus_space_write_4(iot
, ioh
, DBRI_REG0
, tmp
);
835 /* switch CS4215 to data mode - set PIO3 to 1 */
836 tmp
= DBRI_PIO_ENABLE_ALL
| DBRI_PIO1
| DBRI_PIO3
;
839 tmp
|= (sc
->sc_mm
.onboard
? DBRI_PIO0
: DBRI_PIO2
);
841 bus_space_write_4(iot
, ioh
, DBRI_REG2
, tmp
);
842 chi_reset(sc
, CHIslave
, 128);
844 data_width
= sc
->sc_params
.channels
* sc
->sc_params
.precision
;
846 if ((data_width
!= 32) && (data_width
!= 8))
847 aprint_error("%s: data_width is %d\n", __func__
, data_width
);
849 pipe_ts_link(sc
, 20, PIPEoutput
, 16, 32, sc
->sc_mm
.offset
+ 32);
850 pipe_ts_link(sc
, 4, PIPEoutput
, 16, data_width
, sc
->sc_mm
.offset
);
851 pipe_ts_link(sc
, 6, PIPEinput
, 16, data_width
, sc
->sc_mm
.offset
);
852 pipe_ts_link(sc
, 21, PIPEinput
, 16, 32, sc
->sc_mm
.offset
+ 32);
854 pipe_receive_fixed(sc
, 21, &sc
->sc_mm
.status
);
856 mmcodec_setgain(sc
, 0);
858 tmp
= bus_space_read_4(iot
, ioh
, DBRI_REG0
);
859 tmp
|= DBRI_CHI_ACTIVATE
;
860 bus_space_write_4(iot
, ioh
, DBRI_REG0
, tmp
);
866 mmcodec_pipe_init(struct dbri_softc
*sc
)
869 pipe_setup(sc
, 4, DBRI_SDP_MEM
| DBRI_SDP_TO_SER
| DBRI_SDP_MSB
);
870 pipe_setup(sc
, 20, DBRI_SDP_FIXED
| DBRI_SDP_TO_SER
| DBRI_SDP_MSB
);
871 pipe_setup(sc
, 6, DBRI_SDP_MEM
| DBRI_SDP_FROM_SER
| DBRI_SDP_MSB
);
872 pipe_setup(sc
, 21, DBRI_SDP_FIXED
| DBRI_SDP_FROM_SER
| DBRI_SDP_MSB
);
874 pipe_setup(sc
, 17, DBRI_SDP_FIXED
| DBRI_SDP_TO_SER
| DBRI_SDP_MSB
);
875 pipe_setup(sc
, 18, DBRI_SDP_FIXED
| DBRI_SDP_FROM_SER
| DBRI_SDP_MSB
);
876 pipe_setup(sc
, 19, DBRI_SDP_FIXED
| DBRI_SDP_FROM_SER
| DBRI_SDP_MSB
);
878 sc
->sc_mm
.status
= 0;
880 pipe_receive_fixed(sc
, 18, &sc
->sc_mm
.status
);
881 pipe_receive_fixed(sc
, 19, &sc
->sc_mm
.version
);
887 mmcodec_default(struct dbri_softc
*sc
)
889 struct cs4215_state
*mm
= &sc
->sc_mm
;
892 * no action, memory resetting only
894 * data time slots 5-8
895 * speaker, line and headphone enable. set gain to half.
898 mm
->d
.bdata
[0] = sc
->sc_latt
= 0x20 | CS4215_HE
| CS4215_LE
;
899 mm
->d
.bdata
[1] = sc
->sc_ratt
= 0x20 | CS4215_SE
;
903 sc
->sc_input
= 1; /* line */
904 mm
->d
.bdata
[2] = (CS4215_LG((sc
->sc_linp
>> 4)) & 0x0f) |
905 ((sc
->sc_input
== 2) ? CS4215_IS
: 0) | CS4215_PIO0
| CS4215_PIO1
;
906 mm
->d
.bdata
[3] = (CS4215_RG((sc
->sc_rinp
>> 4) & 0x0f)) |
907 CS4215_MA(15 - ((sc
->sc_monitor
>> 4) & 0x0f));
911 * control time slots 1-4
913 * 0: default I/O voltage scale
914 * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled
915 * 2: serial enable, CHI master, 128 bits per frame, clock 1
918 mm
->c
.bcontrol
[0] = CS4215_RSRVD_1
| CS4215_MLB
;
919 mm
->c
.bcontrol
[1] = CS4215_DFR_ULAW
| CS4215_FREQ
[0].csval
;
920 mm
->c
.bcontrol
[2] = CS4215_XCLK
| CS4215_BSEL_128
| CS4215_FREQ
[0].xtal
;
921 mm
->c
.bcontrol
[3] = 0;
927 mmcodec_setgain(struct dbri_softc
*sc
, int mute
)
930 /* disable all outputs, max. attenuation */
931 sc
->sc_mm
.d
.bdata
[0] = sc
->sc_latt
| 63;
932 sc
->sc_mm
.d
.bdata
[1] = sc
->sc_ratt
| 63;
935 sc
->sc_mm
.d
.bdata
[0] = sc
->sc_latt
;
936 sc
->sc_mm
.d
.bdata
[1] = sc
->sc_ratt
;
940 sc
->sc_mm
.d
.bdata
[2] = CS4215_LG((sc
->sc_linp
>> 4) & 0x0f) |
941 ((sc
->sc_input
== 2) ? CS4215_IS
: 0) | CS4215_PIO0
| CS4215_PIO1
;
942 sc
->sc_mm
.d
.bdata
[3] = (CS4215_RG((sc
->sc_rinp
>> 4)) & 0x0f) |
943 (CS4215_MA(15 - ((sc
->sc_monitor
>> 4) & 0x0f)));
945 if (sc
->sc_powerstate
== 0)
947 pipe_transmit_fixed(sc
, 20, sc
->sc_mm
.d
.ldata
);
949 DPRINTF("mmcodec_setgain: %08x\n", sc
->sc_mm
.d
.ldata
);
950 /* give the chip some time to execute the command */
957 mmcodec_setcontrol(struct dbri_softc
*sc
)
959 bus_space_tag_t iot
= sc
->sc_iot
;
960 bus_space_handle_t ioh
= sc
->sc_ioh
;
969 * Temporarily mute outputs and wait 125 us to make sure that it
970 * happens. This avoids clicking noises.
972 mmcodec_setgain(sc
, 1);
975 bus_space_write_4(iot
, ioh
, DBRI_REG2
, 0);
978 /* enable control mode */
979 val
= DBRI_PIO_ENABLE_ALL
| DBRI_PIO1
; /* was PIO1 */
982 val
|= (sc
->sc_mm
.onboard
? DBRI_PIO0
: DBRI_PIO2
);
984 bus_space_write_4(iot
, ioh
, DBRI_REG2
, val
);
989 * in control mode, the cs4215 is the slave device, so the
990 * DBRI must act as the CHI master.
992 * in data mode, the cs4215 must be the CHI master to insure
993 * that the data stream is in sync with its codec
995 tmp
= bus_space_read_4(iot
, ioh
, DBRI_REG0
);
996 tmp
&= ~DBRI_COMMAND_CHI
;
997 bus_space_write_4(iot
, ioh
, DBRI_REG0
, tmp
);
999 chi_reset(sc
, CHImaster
, 128);
1002 pipe_ts_link(sc
, 17, PIPEoutput
, 16, 32, sc
->sc_mm
.offset
);
1003 pipe_ts_link(sc
, 18, PIPEinput
, 16, 8, sc
->sc_mm
.offset
);
1004 pipe_ts_link(sc
, 19, PIPEinput
, 16, 8, sc
->sc_mm
.offset
+ 48);
1006 /* wait for the chip to echo back CLB as zero */
1007 sc
->sc_mm
.c
.bcontrol
[0] &= ~CS4215_CLB
;
1008 pipe_transmit_fixed(sc
, 17, sc
->sc_mm
.c
.lcontrol
);
1010 tmp
= bus_space_read_4(iot
, ioh
, DBRI_REG0
);
1011 tmp
|= DBRI_CHI_ACTIVATE
;
1012 bus_space_write_4(iot
, ioh
, DBRI_REG0
, tmp
);
1016 while (((sc
->sc_mm
.status
& 0xe4) != 0x20) && --i
) {
1021 DPRINTF("%s: cs4215 didn't respond to CLB (0x%02x)\n",
1022 device_xname(sc
->sc_dev
), sc
->sc_mm
.status
);
1026 while (((sc
->sc_mm
.status
& 0xe4) != 0x20) && (bail
< 10)) {
1027 DPRINTF("%s: tsleep %p\n", device_xname(sc
->sc_dev
), sc
);
1028 tsleep(sc
, PCATCH
| PZERO
, "dbrifxdt", hz
);
1033 DPRINTF("%s: switching to control mode timed out (%x %x)\n",
1034 device_xname(sc
->sc_dev
), sc
->sc_mm
.status
,
1035 bus_space_read_4(iot
, ioh
, DBRI_REG2
));
1039 /* copy the version information before it becomes unreadable again */
1040 sc
->sc_version
= sc
->sc_mm
.version
;
1042 /* terminate cs4215 control mode */
1043 sc
->sc_mm
.c
.bcontrol
[0] |= CS4215_CLB
;
1044 pipe_transmit_fixed(sc
, 17, sc
->sc_mm
.c
.lcontrol
);
1046 /* two frames of control info @ 8kHz frame rate = 250us delay */
1049 mmcodec_setgain(sc
, 0);
1059 chi_reset(struct dbri_softc
*sc
, enum ms ms
, int bpf
)
1061 volatile uint32_t *cmd
;
1063 int clockrate
, divisor
;
1065 cmd
= dbri_command_lock(sc
);
1067 /* set CHI anchor: pipe 16 */
1068 val
= DBRI_DTS_VI
| DBRI_DTS_INS
| DBRI_DTS_PRVIN(16) | DBRI_PIPE(16);
1069 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_DTS
, 0, val
);
1070 *(cmd
++) = DBRI_TS_ANCHOR
| DBRI_TS_NEXT(16);
1073 val
= DBRI_DTS_VO
| DBRI_DTS_INS
| DBRI_DTS_PRVOUT(16) | DBRI_PIPE(16);
1074 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_DTS
, 0, val
);
1076 *(cmd
++) = DBRI_TS_ANCHOR
| DBRI_TS_NEXT(16);
1078 sc
->sc_pipe
[16].sdp
= 1;
1079 sc
->sc_pipe
[16].next
= 16;
1080 sc
->sc_chi_pipe_in
= 16;
1081 sc
->sc_chi_pipe_out
= 16;
1085 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_CHI
, 0, DBRI_CHI_CHICM(0));
1088 clockrate
= bpf
* 8;
1089 divisor
= 12288 / clockrate
;
1091 if (divisor
> 255 || divisor
* clockrate
!= 12288)
1092 aprint_error_dev(sc
->sc_dev
,
1093 "illegal bits-per-frame %d\n", bpf
);
1095 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_CHI
, 0,
1096 DBRI_CHI_CHICM(divisor
) | DBRI_CHI_FD
| DBRI_CHI_BPF(bpf
));
1099 aprint_error_dev(sc
->sc_dev
, "unknown value for ms!\n");
1103 sc
->sc_chi_bpf
= bpf
;
1106 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_PAUSE
, 0, 0);
1107 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_CDM
, 0,
1108 DBRI_CDM_XCE
| DBRI_CDM_XEN
| DBRI_CDM_REN
);
1110 dbri_command_send(sc
, cmd
);
1119 pipe_setup(struct dbri_softc
*sc
, int pipe
, int sdp
)
1121 DPRINTF("pipe setup: %d\n", pipe
);
1122 if (pipe
< 0 || pipe
>= DBRI_PIPE_MAX
) {
1123 aprint_error_dev(sc
->sc_dev
, "illegal pipe number %d\n",
1128 if ((sdp
& 0xf800) != sdp
)
1129 aprint_error_dev(sc
->sc_dev
, "strange SDP value %d\n",
1132 if (DBRI_SDP_MODE(sdp
) == DBRI_SDP_FIXED
&&
1133 !(sdp
& DBRI_SDP_TO_SER
))
1134 sdp
|= DBRI_SDP_CHANGE
;
1136 sdp
|= DBRI_PIPE(pipe
);
1138 sc
->sc_pipe
[pipe
].sdp
= sdp
;
1139 sc
->sc_pipe
[pipe
].desc
= -1;
1141 pipe_reset(sc
, pipe
);
1147 pipe_reset(struct dbri_softc
*sc
, int pipe
)
1149 struct dbri_desc
*dd
;
1152 volatile uint32_t *cmd
;
1154 if (pipe
< 0 || pipe
>= DBRI_PIPE_MAX
) {
1155 aprint_error_dev(sc
->sc_dev
, "illegal pipe number %d\n",
1160 sdp
= sc
->sc_pipe
[pipe
].sdp
;
1162 aprint_error_dev(sc
->sc_dev
, "can not reset uninitialized pipe %d\n",
1167 cmd
= dbri_command_lock(sc
);
1168 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_SDP
, 0,
1169 sdp
| DBRI_SDP_CLEAR
| DBRI_SDP_VALID_POINTER
);
1171 dbri_command_send(sc
, cmd
);
1173 desc
= sc
->sc_pipe
[pipe
].desc
;
1175 dd
= &sc
->sc_desc
[desc
];
1181 softint_schedule(dd
->softint
);
1184 sc
->sc_pipe
[pipe
].desc
= -1;
1190 pipe_receive_fixed(struct dbri_softc
*sc
, int pipe
, volatile uint32_t *prec
)
1193 if (pipe
< DBRI_PIPE_MAX
/ 2 || pipe
>= DBRI_PIPE_MAX
) {
1194 aprint_error_dev(sc
->sc_dev
, "illegal pipe number %d\n",
1199 if (DBRI_SDP_MODE(sc
->sc_pipe
[pipe
].sdp
) != DBRI_SDP_FIXED
) {
1200 aprint_error_dev(sc
->sc_dev
, "non-fixed pipe %d\n",
1205 if (sc
->sc_pipe
[pipe
].sdp
& DBRI_SDP_TO_SER
) {
1206 aprint_error_dev(sc
->sc_dev
, "can not receive on transmit pipe %d\b",
1211 sc
->sc_pipe
[pipe
].prec
= prec
;
1217 pipe_transmit_fixed(struct dbri_softc
*sc
, int pipe
, uint32_t data
)
1219 volatile uint32_t *cmd
;
1221 if (pipe
< DBRI_PIPE_MAX
/ 2 || pipe
>= DBRI_PIPE_MAX
) {
1222 aprint_error_dev(sc
->sc_dev
, "illegal pipe number %d\n",
1227 if (DBRI_SDP_MODE(sc
->sc_pipe
[pipe
].sdp
) == 0) {
1228 aprint_error_dev(sc
->sc_dev
, "uninitialized pipe %d\n",
1233 if (DBRI_SDP_MODE(sc
->sc_pipe
[pipe
].sdp
) != DBRI_SDP_FIXED
) {
1234 aprint_error_dev(sc
->sc_dev
, "non-fixed pipe %d\n",
1239 if (!(sc
->sc_pipe
[pipe
].sdp
& DBRI_SDP_TO_SER
)) {
1240 aprint_error_dev(sc
->sc_dev
, "called on receive pipe %d\n",
1245 if (sc
->sc_pipe
[pipe
].sdp
& DBRI_SDP_MSB
)
1246 data
= reverse_bytes(data
, sc
->sc_pipe
[pipe
].length
);
1248 cmd
= dbri_command_lock(sc
);
1249 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_SSP
, 0, pipe
);
1252 dbri_command_send(sc
, cmd
);
1258 setup_ring_xmit(struct dbri_softc
*sc
, int pipe
, int which
, int num
, int blksz
,
1259 void (*callback
)(void *), void *callback_args
)
1261 volatile uint32_t *cmd
;
1264 int td_first
, td_last
;
1265 bus_addr_t dmabuf
, dmabase
;
1266 struct dbri_desc
*dd
= &sc
->sc_desc
[which
];
1270 /* output, offset 0 */
1273 aprint_error("%s: illegal pipe number (%d)\n",
1279 td_first
= td_last
= -1;
1281 if (sc
->sc_pipe
[pipe
].sdp
== 0) {
1282 aprint_error_dev(sc
->sc_dev
, "uninitialized pipe %d\n",
1287 dmabuf
= dd
->dmabase
;
1288 dmabase
= sc
->sc_dmabase
;
1291 for (i
= 0; i
< (num
- 1); i
++) {
1293 sc
->sc_dma
->xmit
[i
].flags
= TX_BCNT(blksz
)
1295 sc
->sc_dma
->xmit
[i
].ba
= dmabuf
;
1296 sc
->sc_dma
->xmit
[i
].nda
= dmabase
+ dbri_dma_off(xmit
, i
+ 1);
1297 sc
->sc_dma
->xmit
[i
].status
= 0;
1303 sc
->sc_dma
->xmit
[i
].flags
= TX_BCNT(blksz
) | TX_EOF
| TX_BINT
;
1305 sc
->sc_dma
->xmit
[i
].ba
= dmabuf
;
1306 sc
->sc_dma
->xmit
[i
].nda
= dmabase
+ dbri_dma_off(xmit
, 0);
1307 sc
->sc_dma
->xmit
[i
].status
= 0;
1309 dd
->callback
= callback
;
1310 dd
->callback_args
= callback_args
;
1314 /* the pipe shouldn't be active */
1315 if (pipe_active(sc
, pipe
)) {
1316 aprint_error("pipe active (CDP)\n");
1317 /* pipe is already active */
1319 td_last
= sc
->sc_pipe
[pipe
].desc
;
1320 while (sc
->sc_desc
[td_last
].next
!= -1)
1321 td_last
= sc
->sc_desc
[td_last
].next
;
1323 sc
->sc_desc
[td_last
].next
= td_first
;
1324 sc
->sc_dma
->desc
[td_last
].nda
=
1325 sc
->sc_dmabase
+ dbri_dma_off(desc
, td_first
);
1327 cmd
= dbri_command_lock(sc
);
1328 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_CDP
, 0, pipe
);
1329 dbri_command_send(sc
, cmd
);
1333 * pipe isn't active - issue an SDP command to start our
1334 * chain of TDs running
1336 sc
->sc_pipe
[pipe
].desc
= which
;
1337 cmd
= dbri_command_lock(sc
);
1338 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_SDP
, 0,
1339 sc
->sc_pipe
[pipe
].sdp
|
1340 DBRI_SDP_VALID_POINTER
|
1343 *(cmd
++) = sc
->sc_dmabase
+ dbri_dma_off(xmit
, 0);
1344 dbri_command_send(sc
, cmd
);
1345 DPRINTF("%s: starting DMA\n", __func__
);
1354 setup_ring_recv(struct dbri_softc
*sc
, int pipe
, int which
, int num
, int blksz
,
1355 void (*callback
)(void *), void *callback_args
)
1357 volatile uint32_t *cmd
;
1359 int td_first
, td_last
;
1360 bus_addr_t dmabuf
, dmabase
;
1361 struct dbri_desc
*dd
= &sc
->sc_desc
[which
];
1367 aprint_error("%s: illegal pipe number (%d)\n",
1372 td_first
= td_last
= -1;
1374 if (sc
->sc_pipe
[pipe
].sdp
== 0) {
1375 aprint_error_dev(sc
->sc_dev
, "uninitialized pipe %d\n",
1380 dmabuf
= dd
->dmabase
;
1381 dmabase
= sc
->sc_dmabase
;
1383 for (i
= 0; i
< (num
- 1); i
++) {
1385 sc
->sc_dma
->recv
[i
].flags
= RX_BSIZE(blksz
) | RX_FINAL
;
1386 sc
->sc_dma
->recv
[i
].ba
= dmabuf
;
1387 sc
->sc_dma
->recv
[i
].nda
= dmabase
+ dbri_dma_off(recv
, i
+ 1);
1388 sc
->sc_dma
->recv
[i
].status
= RX_EOF
;
1394 sc
->sc_dma
->recv
[i
].flags
= RX_BSIZE(blksz
) | RX_FINAL
;
1396 sc
->sc_dma
->recv
[i
].ba
= dmabuf
;
1397 sc
->sc_dma
->recv
[i
].nda
= dmabase
+ dbri_dma_off(recv
, 0);
1398 sc
->sc_dma
->recv
[i
].status
= RX_EOF
;
1400 dd
->callback
= callback
;
1401 dd
->callback_args
= callback_args
;
1405 /* the pipe shouldn't be active */
1406 if (pipe_active(sc
, pipe
)) {
1407 aprint_error("pipe active (CDP)\n");
1408 /* pipe is already active */
1410 td_last
= sc
->sc_pipe
[pipe
].desc
;
1411 while (sc
->sc_desc
[td_last
].next
!= -1)
1412 td_last
= sc
->sc_desc
[td_last
].next
;
1414 sc
->sc_desc
[td_last
].next
= td_first
;
1415 sc
->sc_dma
->desc
[td_last
].nda
=
1416 sc
->sc_dmabase
+ dbri_dma_off(desc
, td_first
);
1418 cmd
= dbri_command_lock(sc
);
1419 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_CDP
, 0, pipe
);
1420 dbri_command_send(sc
, cmd
);
1424 * pipe isn't active - issue an SDP command to start our
1425 * chain of TDs running
1427 sc
->sc_pipe
[pipe
].desc
= which
;
1428 cmd
= dbri_command_lock(sc
);
1429 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_SDP
, 0,
1430 sc
->sc_pipe
[pipe
].sdp
|
1431 DBRI_SDP_VALID_POINTER
|
1434 *(cmd
++) = sc
->sc_dmabase
+ dbri_dma_off(recv
, 0);
1435 dbri_command_send(sc
, cmd
);
1436 DPRINTF("%s: starting DMA\n", __func__
);
1445 pipe_ts_link(struct dbri_softc
*sc
, int pipe
, enum io dir
, int basepipe
,
1448 volatile uint32_t *cmd
;
1449 int prevpipe
, nextpipe
;
1452 DPRINTF("%s: %d\n", __func__
, pipe
);
1453 if (pipe
< 0 || pipe
>= DBRI_PIPE_MAX
||
1454 basepipe
< 0 || basepipe
>= DBRI_PIPE_MAX
) {
1455 aprint_error_dev(sc
->sc_dev
, "illegal pipe numbers (%d, %d)\n",
1460 if (sc
->sc_pipe
[pipe
].sdp
== 0 || sc
->sc_pipe
[basepipe
].sdp
== 0) {
1461 aprint_error_dev(sc
->sc_dev
, "uninitialized pipe (%d, %d)\n",
1466 if (basepipe
== 16 && dir
== PIPEoutput
&& cycle
== 0)
1467 cycle
= sc
->sc_chi_bpf
;
1469 if (basepipe
== pipe
)
1470 prevpipe
= nextpipe
= pipe
;
1472 if (basepipe
== 16) {
1473 if (dir
== PIPEinput
) {
1474 prevpipe
= sc
->sc_chi_pipe_in
;
1476 prevpipe
= sc
->sc_chi_pipe_out
;
1479 prevpipe
= basepipe
;
1481 nextpipe
= sc
->sc_pipe
[prevpipe
].next
;
1483 while (sc
->sc_pipe
[nextpipe
].cycle
< cycle
&&
1484 sc
->sc_pipe
[nextpipe
].next
!= basepipe
) {
1485 prevpipe
= nextpipe
;
1486 nextpipe
= sc
->sc_pipe
[nextpipe
].next
;
1490 if (prevpipe
== 16) {
1491 if (dir
== PIPEinput
) {
1492 sc
->sc_chi_pipe_in
= pipe
;
1494 sc
->sc_chi_pipe_out
= pipe
;
1497 sc
->sc_pipe
[prevpipe
].next
= pipe
;
1499 sc
->sc_pipe
[pipe
].next
= nextpipe
;
1500 sc
->sc_pipe
[pipe
].cycle
= cycle
;
1501 sc
->sc_pipe
[pipe
].length
= len
;
1503 cmd
= dbri_command_lock(sc
);
1507 val
= DBRI_DTS_VI
| DBRI_DTS_INS
| DBRI_DTS_PRVIN(prevpipe
);
1509 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_DTS
, 0, val
);
1510 *(cmd
++) = DBRI_TS_LEN(len
) | DBRI_TS_CYCLE(cycle
) |
1511 DBRI_TS_NEXT(nextpipe
);
1515 val
= DBRI_DTS_VO
| DBRI_DTS_INS
| DBRI_DTS_PRVOUT(prevpipe
);
1517 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_DTS
, 0, val
);
1519 *(cmd
++) = DBRI_TS_LEN(len
) | DBRI_TS_CYCLE(cycle
) |
1520 DBRI_TS_NEXT(nextpipe
);
1523 DPRINTF("%s: should not have happened!\n",
1524 device_xname(sc
->sc_dev
));
1528 dbri_command_send(sc
, cmd
);
1534 pipe_active(struct dbri_softc
*sc
, int pipe
)
1537 return (sc
->sc_pipe
[pipe
].desc
!= -1);
1541 * subroutines required to interface with audio(9)
1545 dbri_query_encoding(void *hdl
, struct audio_encoding
*ae
)
1548 switch (ae
->index
) {
1550 strcpy(ae
->name
, AudioEulinear
);
1551 ae
->encoding
= AUDIO_ENCODING_ULINEAR
;
1556 strcpy(ae
->name
, AudioEmulaw
);
1557 ae
->encoding
= AUDIO_ENCODING_ULAW
;
1562 strcpy(ae
->name
, AudioEalaw
);
1563 ae
->encoding
= AUDIO_ENCODING_ALAW
;
1568 strcpy(ae
->name
, AudioEslinear
);
1569 ae
->encoding
= AUDIO_ENCODING_SLINEAR
;
1571 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
1574 strcpy(ae
->name
, AudioEslinear_le
);
1575 ae
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
1577 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
1580 strcpy(ae
->name
, AudioEulinear_le
);
1581 ae
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
1583 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
1586 strcpy(ae
->name
, AudioEslinear_be
);
1587 ae
->encoding
= AUDIO_ENCODING_SLINEAR_BE
;
1592 strcpy(ae
->name
, AudioEulinear_be
);
1593 ae
->encoding
= AUDIO_ENCODING_ULINEAR_BE
;
1595 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
1598 strcpy(ae
->name
, AudioEslinear
);
1599 ae
->encoding
= AUDIO_ENCODING_SLINEAR
;
1611 dbri_set_params(void *hdl
, int setmode
, int usemode
,
1612 struct audio_params
*play
, struct audio_params
*rec
,
1613 stream_filter_list_t
*pfil
, stream_filter_list_t
*rfil
)
1615 struct dbri_softc
*sc
= hdl
;
1617 audio_params_t
*p
= NULL
;
1618 stream_filter_list_t
*fil
;
1622 * This device only has one clock, so make the sample rates match.
1624 if (play
->sample_rate
!= rec
->sample_rate
&&
1625 usemode
== (AUMODE_PLAY
| AUMODE_RECORD
)) {
1626 if (setmode
== AUMODE_PLAY
) {
1627 rec
->sample_rate
= play
->sample_rate
;
1628 setmode
|= AUMODE_RECORD
;
1629 } else if (setmode
== AUMODE_RECORD
) {
1630 play
->sample_rate
= rec
->sample_rate
;
1631 setmode
|= AUMODE_PLAY
;
1636 for (mode
= AUMODE_RECORD
; mode
!= -1;
1637 mode
= mode
== AUMODE_RECORD
? AUMODE_PLAY
: -1) {
1638 if ((setmode
& mode
) == 0)
1641 p
= mode
== AUMODE_PLAY
? play
: rec
;
1642 if (p
->sample_rate
< 4000 || p
->sample_rate
> 50000) {
1643 DPRINTF("dbri_set_params: invalid rate %d\n",
1648 fil
= mode
== AUMODE_PLAY
? pfil
: rfil
;
1649 DPRINTF("requested enc: %d rate: %d prec: %d chan: %d\n", p
->encoding
,
1650 p
->sample_rate
, p
->precision
, p
->channels
);
1651 if (auconv_set_converter(dbri_formats
, DBRI_NFORMATS
,
1652 mode
, p
, true, fil
) < 0) {
1653 aprint_debug("dbri_set_params: auconv_set_converter failed\n");
1656 if (fil
->req_size
> 0)
1657 p
= &fil
->filters
[0].param
;
1661 DPRINTF("dbri_set_params: no parameters to set\n");
1665 DPRINTF("native enc: %d rate: %d prec: %d chan: %d\n", p
->encoding
,
1666 p
->sample_rate
, p
->precision
, p
->channels
);
1668 for (rate
= 0; CS4215_FREQ
[rate
].freq
; rate
++)
1669 if (CS4215_FREQ
[rate
].freq
== p
->sample_rate
)
1672 if (CS4215_FREQ
[rate
].freq
== 0)
1676 sc
->sc_mm
.c
.bcontrol
[1] &= ~0x38;
1677 sc
->sc_mm
.c
.bcontrol
[1] |= CS4215_FREQ
[rate
].csval
;
1678 sc
->sc_mm
.c
.bcontrol
[2] &= ~0x70;
1679 sc
->sc_mm
.c
.bcontrol
[2] |= CS4215_FREQ
[rate
].xtal
;
1681 switch (p
->encoding
) {
1682 case AUDIO_ENCODING_ULAW
:
1683 sc
->sc_mm
.c
.bcontrol
[1] &= ~3;
1684 sc
->sc_mm
.c
.bcontrol
[1] |= CS4215_DFR_ULAW
;
1686 case AUDIO_ENCODING_ALAW
:
1687 sc
->sc_mm
.c
.bcontrol
[1] &= ~3;
1688 sc
->sc_mm
.c
.bcontrol
[1] |= CS4215_DFR_ALAW
;
1690 case AUDIO_ENCODING_ULINEAR
:
1691 sc
->sc_mm
.c
.bcontrol
[1] &= ~3;
1692 if (p
->precision
== 8) {
1693 sc
->sc_mm
.c
.bcontrol
[1] |= CS4215_DFR_LINEAR8
;
1695 sc
->sc_mm
.c
.bcontrol
[1] |= CS4215_DFR_LINEAR16
;
1698 case AUDIO_ENCODING_SLINEAR_BE
:
1699 case AUDIO_ENCODING_SLINEAR
:
1700 sc
->sc_mm
.c
.bcontrol
[1] &= ~3;
1701 sc
->sc_mm
.c
.bcontrol
[1] |= CS4215_DFR_LINEAR16
;
1705 switch (p
->channels
) {
1707 sc
->sc_mm
.c
.bcontrol
[1] &= ~CS4215_DFR_STEREO
;
1710 sc
->sc_mm
.c
.bcontrol
[1] |= CS4215_DFR_STEREO
;
1718 dbri_round_blocksize(void *hdl
, int bs
, int mode
,
1719 const audio_params_t
*param
)
1722 /* DBRI DMA segment size, rounded down to 32bit alignment */
1727 dbri_halt_output(void *hdl
)
1729 struct dbri_softc
*sc
= hdl
;
1731 if (!sc
->sc_playing
)
1740 dbri_getdev(void *hdl
, struct audio_device
*ret
)
1748 dbri_set_port(void *hdl
, mixer_ctrl_t
*mc
)
1750 struct dbri_softc
*sc
= hdl
;
1751 int latt
= sc
->sc_latt
, ratt
= sc
->sc_ratt
;
1754 case DBRI_VOL_OUTPUT
: /* master volume */
1755 latt
= (latt
& 0xc0) | (63 -
1756 min(mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
] >> 2, 63));
1757 ratt
= (ratt
& 0xc0) | (63 -
1758 min(mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
] >> 2, 63));
1760 case DBRI_ENABLE_MONO
: /* built-in speaker */
1761 if (mc
->un
.ord
== 1) {
1766 case DBRI_ENABLE_HEADPHONE
: /* headphones output */
1767 if (mc
->un
.ord
== 1) {
1772 case DBRI_ENABLE_LINE
: /* line out */
1773 if (mc
->un
.ord
== 1) {
1778 case DBRI_VOL_MONITOR
:
1779 if (mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
] ==
1782 sc
->sc_monitor
= mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
];
1784 case DBRI_INPUT_GAIN
:
1785 sc
->sc_linp
= mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
];
1786 sc
->sc_rinp
= mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
];
1788 case DBRI_INPUT_SELECT
:
1789 if (mc
->un
.mask
== sc
->sc_input
)
1791 sc
->sc_input
= mc
->un
.mask
;
1798 mmcodec_setgain(sc
, 0);
1804 dbri_get_port(void *hdl
, mixer_ctrl_t
*mc
)
1806 struct dbri_softc
*sc
= hdl
;
1809 case DBRI_VOL_OUTPUT
: /* master volume */
1810 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
] =
1811 (63 - (sc
->sc_latt
& 0x3f)) << 2;
1812 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
] =
1813 (63 - (sc
->sc_ratt
& 0x3f)) << 2;
1815 case DBRI_ENABLE_MONO
: /* built-in speaker */
1816 mc
->un
.ord
= (sc
->sc_ratt
& CS4215_SE
) ? 1 : 0;
1818 case DBRI_ENABLE_HEADPHONE
: /* headphones output */
1819 mc
->un
.ord
= (sc
->sc_latt
& CS4215_HE
) ? 1 : 0;
1821 case DBRI_ENABLE_LINE
: /* line out */
1822 mc
->un
.ord
= (sc
->sc_latt
& CS4215_LE
) ? 1 : 0;
1824 case DBRI_VOL_MONITOR
:
1825 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
] = sc
->sc_monitor
;
1827 case DBRI_INPUT_GAIN
:
1828 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
] = sc
->sc_linp
;
1829 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
] = sc
->sc_rinp
;
1831 case DBRI_INPUT_SELECT
:
1832 mc
->un
.mask
= sc
->sc_input
;
1839 dbri_query_devinfo(void *hdl
, mixer_devinfo_t
*di
)
1842 switch (di
->index
) {
1843 case DBRI_MONITOR_CLASS
:
1844 di
->mixer_class
= DBRI_MONITOR_CLASS
;
1845 strcpy(di
->label
.name
, AudioCmonitor
);
1846 di
->type
= AUDIO_MIXER_CLASS
;
1847 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1849 case DBRI_OUTPUT_CLASS
:
1850 di
->mixer_class
= DBRI_OUTPUT_CLASS
;
1851 strcpy(di
->label
.name
, AudioCoutputs
);
1852 di
->type
= AUDIO_MIXER_CLASS
;
1853 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1855 case DBRI_INPUT_CLASS
:
1856 di
->mixer_class
= DBRI_INPUT_CLASS
;
1857 strcpy(di
->label
.name
, AudioCinputs
);
1858 di
->type
= AUDIO_MIXER_CLASS
;
1859 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1861 case DBRI_VOL_OUTPUT
: /* master volume */
1862 di
->mixer_class
= DBRI_OUTPUT_CLASS
;
1863 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1864 strcpy(di
->label
.name
, AudioNmaster
);
1865 di
->type
= AUDIO_MIXER_VALUE
;
1866 di
->un
.v
.num_channels
= 2;
1867 strcpy(di
->un
.v
.units
.name
, AudioNvolume
);
1869 case DBRI_INPUT_GAIN
: /* input gain */
1870 di
->mixer_class
= DBRI_INPUT_CLASS
;
1871 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1872 strcpy(di
->label
.name
, AudioNrecord
);
1873 di
->type
= AUDIO_MIXER_VALUE
;
1874 di
->un
.v
.num_channels
= 2;
1875 strcpy(di
->un
.v
.units
.name
, AudioNvolume
);
1877 case DBRI_VOL_MONITOR
: /* monitor volume */
1878 di
->mixer_class
= DBRI_MONITOR_CLASS
;
1879 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1880 strcpy(di
->label
.name
, AudioNmonitor
);
1881 di
->type
= AUDIO_MIXER_VALUE
;
1882 di
->un
.v
.num_channels
= 1;
1883 strcpy(di
->un
.v
.units
.name
, AudioNvolume
);
1885 case DBRI_ENABLE_MONO
: /* built-in speaker */
1886 di
->mixer_class
= DBRI_OUTPUT_CLASS
;
1887 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1888 strcpy(di
->label
.name
, AudioNmono
);
1889 di
->type
= AUDIO_MIXER_ENUM
;
1890 di
->un
.e
.num_mem
= 2;
1891 strcpy(di
->un
.e
.member
[0].label
.name
, AudioNoff
);
1892 di
->un
.e
.member
[0].ord
= 0;
1893 strcpy(di
->un
.e
.member
[1].label
.name
, AudioNon
);
1894 di
->un
.e
.member
[1].ord
= 1;
1896 case DBRI_ENABLE_HEADPHONE
: /* headphones output */
1897 di
->mixer_class
= DBRI_OUTPUT_CLASS
;
1898 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1899 strcpy(di
->label
.name
, AudioNheadphone
);
1900 di
->type
= AUDIO_MIXER_ENUM
;
1901 di
->un
.e
.num_mem
= 2;
1902 strcpy(di
->un
.e
.member
[0].label
.name
, AudioNoff
);
1903 di
->un
.e
.member
[0].ord
= 0;
1904 strcpy(di
->un
.e
.member
[1].label
.name
, AudioNon
);
1905 di
->un
.e
.member
[1].ord
= 1;
1907 case DBRI_ENABLE_LINE
: /* line out */
1908 di
->mixer_class
= DBRI_OUTPUT_CLASS
;
1909 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
1910 strcpy(di
->label
.name
, AudioNline
);
1911 di
->type
= AUDIO_MIXER_ENUM
;
1912 di
->un
.e
.num_mem
= 2;
1913 strcpy(di
->un
.e
.member
[0].label
.name
, AudioNoff
);
1914 di
->un
.e
.member
[0].ord
= 0;
1915 strcpy(di
->un
.e
.member
[1].label
.name
, AudioNon
);
1916 di
->un
.e
.member
[1].ord
= 1;
1918 case DBRI_INPUT_SELECT
:
1919 di
->mixer_class
= DBRI_INPUT_CLASS
;
1920 strcpy(di
->label
.name
, AudioNsource
);
1921 di
->type
= AUDIO_MIXER_SET
;
1922 di
->prev
= di
->next
= AUDIO_MIXER_LAST
;
1923 di
->un
.s
.num_mem
= 2;
1924 strcpy(di
->un
.s
.member
[0].label
.name
, AudioNline
);
1925 di
->un
.s
.member
[0].mask
= 1 << 0;
1926 strcpy(di
->un
.s
.member
[1].label
.name
, AudioNmicrophone
);
1927 di
->un
.s
.member
[1].mask
= 1 << 1;
1935 dbri_round_buffersize(void *hdl
, int dir
, size_t bufsize
)
1937 #ifdef DBRI_BIG_BUFFER
1938 return 16*0x1ffc; /* use ~128KB buffer */
1945 dbri_get_props(void *hdl
)
1948 return AUDIO_PROP_MMAP
| AUDIO_PROP_FULLDUPLEX
;
1952 dbri_trigger_output(void *hdl
, void *start
, void *end
, int blksize
,
1953 void (*intr
)(void *), void *intrarg
,
1954 const struct audio_params
*param
)
1956 struct dbri_softc
*sc
= hdl
;
1957 unsigned long count
, num
;
1962 count
= (unsigned long)(((char *)end
- (char *)start
));
1963 num
= count
/ blksize
;
1965 DPRINTF("trigger_output(%lx %lx) : %d %ld %ld\n",
1966 (unsigned long)intr
,
1967 (unsigned long)intrarg
, blksize
, count
, num
);
1969 sc
->sc_params
= *param
;
1971 if (sc
->sc_recording
== 0) {
1972 /* do not muck with the codec when it's already in use */
1973 if (mmcodec_setcontrol(sc
) != 0)
1975 mmcodec_init_data(sc
);
1979 * always use DMA descriptor 0 for output
1980 * no need to allocate them dynamically since we only ever have
1981 * exactly one input stream and exactly one output stream
1983 setup_ring_xmit(sc
, 4, 0, num
, blksize
, intr
, intrarg
);
1989 dbri_halt_input(void *cookie
)
1991 struct dbri_softc
*sc
= cookie
;
1993 if (!sc
->sc_recording
)
1996 sc
->sc_recording
= 0;
2002 dbri_trigger_input(void *hdl
, void *start
, void *end
, int blksize
,
2003 void (*intr
)(void *), void *intrarg
,
2004 const struct audio_params
*param
)
2006 struct dbri_softc
*sc
= hdl
;
2007 unsigned long count
, num
;
2009 if (sc
->sc_recording
)
2012 count
= (unsigned long)(((char *)end
- (char *)start
));
2013 num
= count
/ blksize
;
2015 DPRINTF("trigger_input(%lx %lx) : %d %ld %ld\n",
2016 (unsigned long)intr
,
2017 (unsigned long)intrarg
, blksize
, count
, num
);
2019 sc
->sc_params
= *param
;
2021 if (sc
->sc_playing
== 0) {
2024 * we don't support different parameters for playing and
2025 * recording anyway so don't bother whacking the codec if
2026 * it's already set up
2028 mmcodec_setcontrol(sc
);
2029 mmcodec_init_data(sc
);
2032 sc
->sc_recording
= 1;
2033 setup_ring_recv(sc
, 6, 1, num
, blksize
, intr
, intrarg
);
2039 reverse_bytes(uint32_t b
, int len
)
2043 b
= ((b
& 0xffff0000) >> 16) | ((b
& 0x0000ffff) << 16);
2045 b
= ((b
& 0xff00ff00) >> 8) | ((b
& 0x00ff00ff) << 8);
2047 b
= ((b
& 0xf0f0f0f0) >> 4) | ((b
& 0x0f0f0f0f) << 4);
2049 b
= ((b
& 0xcccccccc) >> 2) | ((b
& 0x33333333) << 2);
2051 b
= ((b
& 0xaaaaaaaa) >> 1) | ((b
& 0x55555555) << 1);
2056 DPRINTF("reverse_bytes: unsupported length\n");
2063 dbri_malloc(void *v
, int dir
, size_t s
, struct malloc_type
*mt
, int flags
)
2065 struct dbri_softc
*sc
= v
;
2066 struct dbri_desc
*dd
= &sc
->sc_desc
[sc
->sc_desc_used
];
2069 if (bus_dmamap_create(sc
->sc_dmat
, s
, 1, s
, 0, BUS_DMA_NOWAIT
,
2070 &dd
->dmamap
) == 0) {
2071 if (bus_dmamem_alloc(sc
->sc_dmat
, s
, 0, 0, &dd
->dmaseg
,
2072 1, &rseg
, BUS_DMA_NOWAIT
) == 0) {
2073 if (bus_dmamem_map(sc
->sc_dmat
, &dd
->dmaseg
, rseg
, s
,
2074 &dd
->buf
, BUS_DMA_NOWAIT
|BUS_DMA_COHERENT
) == 0) {
2075 if (dd
->buf
!= NULL
) {
2076 if (bus_dmamap_load(sc
->sc_dmat
,
2077 dd
->dmamap
, dd
->buf
, s
, NULL
,
2078 BUS_DMA_NOWAIT
) == 0) {
2081 dd
->callback
= NULL
;
2083 dd
->dmamap
->dm_segs
[0].ds_addr
;
2084 DPRINTF("dbri_malloc: using buffer %d %08x\n",
2085 sc
->sc_desc_used
, (uint32_t)dd
->buf
);
2089 aprint_error("dbri_malloc: load failed\n");
2091 aprint_error("dbri_malloc: map returned NULL\n");
2093 aprint_error("dbri_malloc: map failed\n");
2094 bus_dmamem_free(sc
->sc_dmat
, &dd
->dmaseg
, rseg
);
2096 aprint_error("dbri_malloc: malloc() failed\n");
2097 bus_dmamap_destroy(sc
->sc_dmat
, dd
->dmamap
);
2099 aprint_error("dbri_malloc: bus_dmamap_create() failed\n");
2104 dbri_free(void *v
, void *p
, struct malloc_type
*mt
)
2106 struct dbri_softc
*sc
= v
;
2107 struct dbri_desc
*dd
;
2110 for (i
= 0; i
< sc
->sc_desc_used
; i
++) {
2111 dd
= &sc
->sc_desc
[i
];
2115 if (i
>= sc
->sc_desc_used
)
2117 bus_dmamap_unload(sc
->sc_dmat
, dd
->dmamap
);
2118 bus_dmamap_destroy(sc
->sc_dmat
, dd
->dmamap
);
2122 dbri_mappage(void *v
, void *mem
, off_t off
, int prot
)
2124 struct dbri_softc
*sc
= v
;
2131 while ((current
< sc
->sc_desc_used
) &&
2132 (sc
->sc_desc
[current
].buf
!= mem
))
2135 if (current
< sc
->sc_desc_used
) {
2136 return bus_dmamem_mmap(sc
->sc_dmat
,
2137 &sc
->sc_desc
[current
].dmaseg
, 1, off
, prot
, BUS_DMA_WAITOK
);
2144 dbri_open(void *cookie
, int flags
)
2146 struct dbri_softc
*sc
= cookie
;
2148 DPRINTF("%s: %d\n", __func__
, sc
->sc_refcount
);
2150 if (sc
->sc_refcount
== 0)
2159 dbri_close(void *cookie
)
2161 struct dbri_softc
*sc
= cookie
;
2163 DPRINTF("%s: %d\n", __func__
, sc
->sc_refcount
);
2166 KASSERT(sc
->sc_refcount
>= 0);
2167 if (sc
->sc_refcount
> 0)
2170 dbri_set_power(sc
, 0);
2172 sc
->sc_recording
= 0;
2176 dbri_suspend(device_t self PMF_FN_ARGS
)
2178 struct dbri_softc
*sc
= device_private(self
);
2180 dbri_set_power(sc
, 0);
2185 dbri_resume(device_t self PMF_FN_ARGS
)
2187 struct dbri_softc
*sc
= device_private(self
);
2189 if (sc
->sc_powerstate
!= 0)
2191 aprint_verbose("resume: %d\n", sc
->sc_refcount
);
2192 if (sc
->sc_playing
) {
2193 volatile uint32_t *cmd
;
2198 cmd
= dbri_command_lock(sc
);
2199 *(cmd
++) = DBRI_CMD(DBRI_COMMAND_SDP
,
2200 0, sc
->sc_pipe
[4].sdp
|
2201 DBRI_SDP_VALID_POINTER
|
2202 DBRI_SDP_EVERY
| DBRI_SDP_CLEAR
);
2203 *(cmd
++) = sc
->sc_dmabase
+
2204 dbri_dma_off(xmit
, 0);
2205 dbri_command_send(sc
, cmd
);
2211 #endif /* NAUDIO > 0 */