xref: /openbsd/sys/arch/macppc/dev/i2s.c (revision 404b540a)
1 /*	$OpenBSD: i2s.c,v 1.17 2008/11/07 19:53:20 todd Exp $	*/
2 /*	$NetBSD: i2s.c,v 1.1 2003/12/27 02:19:34 grant Exp $	*/
3 
4 /*-
5  * Copyright (c) 2002 Tsubai Masanari.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <sys/param.h>
31 #include <sys/audioio.h>
32 #include <sys/device.h>
33 #include <sys/malloc.h>
34 #include <sys/systm.h>
35 
36 #include <dev/auconv.h>
37 #include <dev/audio_if.h>
38 #include <dev/mulaw.h>
39 #include <dev/ofw/openfirm.h>
40 #include <macppc/dev/dbdma.h>
41 
42 #include <uvm/uvm_extern.h>
43 
44 #include <machine/autoconf.h>
45 #include <machine/pio.h>
46 
47 #include <macppc/dev/i2svar.h>
48 #include <macppc/dev/i2sreg.h>
49 
50 #ifdef I2S_DEBUG
51 # define DPRINTF(x) printf x
52 #else
53 # define DPRINTF(x)
54 #endif
55 
56 struct audio_params i2s_audio_default = {
57 	44100,		/* sample_rate */
58 	AUDIO_ENCODING_SLINEAR_BE, /* encoding */
59 	16,		/* precision */
60 	2,		/* channels */
61 	NULL,		/* sw_code */
62 	1		/* factor */
63 };
64 
65 struct i2s_mode *i2s_find_mode(u_int, u_int, u_int);
66 
67 static int gpio_read(char *);
68 static void gpio_write(char *, int);
69 void i2s_mute_speaker(struct i2s_softc *, int);
70 void i2s_mute_headphone(struct i2s_softc *, int);
71 void i2s_mute_lineout(struct i2s_softc *, int);
72 int i2s_cint(void *);
73 u_char *i2s_gpio_map(struct i2s_softc *, char *, int *);
74 void i2s_init(struct i2s_softc *, int);
75 
76 int i2s_intr(void *);
77 int i2s_iintr(void *);
78 
79 /* XXX */
80 void keylargo_fcr_enable(int, u_int32_t);
81 void keylargo_fcr_disable(int, u_int32_t);
82 
83 struct cfdriver i2s_cd = {
84 	NULL, "i2s", DV_DULL
85 };
86 
87 static u_char *amp_mute;
88 static u_char *headphone_mute;
89 static u_char *lineout_mute;
90 static u_char *audio_hw_reset;
91 static u_char *headphone_detect;
92 static int headphone_detect_active;
93 static u_char *lineout_detect;
94 static int lineout_detect_active;
95 
96 /* GPIO bits */
97 #define GPIO_OUTSEL	0xf0	/* Output select */
98 		/*	0x00	GPIO bit0 is output
99 			0x10	media-bay power
100 			0x20	reserved
101 			0x30	MPIC */
102 
103 #define GPIO_ALTOE	0x08	/* Alternate output enable */
104 		/*	0x00	Use DDR
105 			0x08	Use output select */
106 
107 #define GPIO_DDR	0x04	/* Data direction */
108 #define GPIO_DDR_OUTPUT	0x04	/* Output */
109 #define GPIO_DDR_INPUT	0x00	/* Input */
110 
111 #define GPIO_LEVEL	0x02	/* Pin level (RO) */
112 
113 #define	GPIO_DATA	0x01	/* Data */
114 
115 void
116 i2s_attach(struct device *parent, struct i2s_softc *sc, struct confargs *ca)
117 {
118 	int cirq, oirq, iirq, cirq_type, oirq_type, iirq_type;
119 	u_int32_t reg[6], intr[6];
120 
121 	sc->sc_node = OF_child(ca->ca_node);
122 	sc->sc_baseaddr = ca->ca_baseaddr;
123 
124 	OF_getprop(sc->sc_node, "reg", reg, sizeof reg);
125 	reg[0] += sc->sc_baseaddr;
126 	reg[2] += sc->sc_baseaddr;
127 	reg[4] += sc->sc_baseaddr;
128 
129 	sc->sc_reg = mapiodev(reg[0], reg[1]);
130 
131 	sc->sc_dmat = ca->ca_dmat;
132 	sc->sc_odma = mapiodev(reg[2], reg[3]); /* out */
133 	sc->sc_idma = mapiodev(reg[4], reg[5]); /* in */
134 	sc->sc_odbdma = dbdma_alloc(sc->sc_dmat, I2S_DMALIST_MAX);
135 	sc->sc_odmacmd = sc->sc_odbdma->d_addr;
136 	sc->sc_idbdma = dbdma_alloc(sc->sc_dmat, I2S_DMALIST_MAX);
137 	sc->sc_idmacmd = sc->sc_idbdma->d_addr;
138 
139 	OF_getprop(sc->sc_node, "interrupts", intr, sizeof intr);
140 	cirq = intr[0];
141 	oirq = intr[2];
142 	iirq = intr[4];
143 	cirq_type = intr[1] ? IST_LEVEL : IST_EDGE;
144 	oirq_type = intr[3] ? IST_LEVEL : IST_EDGE;
145 	iirq_type = intr[5] ? IST_LEVEL : IST_EDGE;
146 
147 	/* intr_establish(cirq, cirq_type, IPL_AUDIO, i2s_intr, sc); */
148 	mac_intr_establish(parent, oirq, oirq_type, IPL_AUDIO, i2s_intr,
149 	    sc, sc->sc_dev.dv_xname);
150 	mac_intr_establish(parent, iirq, iirq_type, IPL_AUDIO, i2s_iintr,
151 	    sc, sc->sc_dev.dv_xname);
152 
153 	printf(": irq %d,%d,%d\n", cirq, oirq, iirq);
154 
155 	i2s_set_rate(sc, 44100);
156 	i2s_gpio_init(sc, ca->ca_node, parent);
157 }
158 
159 int
160 i2s_intr(v)
161 	void *v;
162 {
163 	struct i2s_softc *sc = v;
164 	struct dbdma_command *cmd = sc->sc_odmap;
165 	u_int16_t c, status;
166 
167 	/* if not set we are not running */
168 	if (!cmd)
169 		return (0);
170 	DPRINTF(("i2s_intr: cmd %x\n", cmd));
171 
172 	c = in16rb(&cmd->d_command);
173 	status = in16rb(&cmd->d_status);
174 
175 	if (c >> 12 == DBDMA_CMD_OUT_LAST)
176 		sc->sc_odmap = sc->sc_odmacmd;
177 	else
178 		sc->sc_odmap++;
179 
180 	if (c & (DBDMA_INT_ALWAYS << 4)) {
181 		cmd->d_status = 0;
182 		if (status)	/* status == 0x8400 */
183 			if (sc->sc_ointr)
184 				(*sc->sc_ointr)(sc->sc_oarg);
185 	}
186 
187 	return 1;
188 }
189 
190 int
191 i2s_iintr(v)
192 	void *v;
193 {
194 	struct i2s_softc *sc = v;
195 	struct dbdma_command *cmd = sc->sc_idmap;
196 	u_int16_t c, status;
197 
198 	/* if not set we are not running */
199 	if (!cmd)
200 		return (0);
201 	DPRINTF(("i2s_intr: cmd %x\n", cmd));
202 
203 	c = in16rb(&cmd->d_command);
204 	status = in16rb(&cmd->d_status);
205 
206 	if (c >> 12 == DBDMA_CMD_IN_LAST)
207 		sc->sc_idmap = sc->sc_idmacmd;
208 	else
209 		sc->sc_idmap++;
210 
211 	if (c & (DBDMA_INT_ALWAYS << 4)) {
212 		cmd->d_status = 0;
213 		if (status)	/* status == 0x8400 */
214 			if (sc->sc_iintr)
215 				(*sc->sc_iintr)(sc->sc_iarg);
216 	}
217 
218 	return 1;
219 }
220 
221 int
222 i2s_open(h, flags)
223 	void *h;
224 	int flags;
225 {
226 	return 0;
227 }
228 
229 /*
230  * Close function is called at splaudio().
231  */
232 void
233 i2s_close(h)
234 	void *h;
235 {
236 	struct i2s_softc *sc = h;
237 
238 	i2s_halt_output(sc);
239 	i2s_halt_input(sc);
240 
241 	sc->sc_ointr = 0;
242 	sc->sc_iintr = 0;
243 }
244 
245 int
246 i2s_query_encoding(h, ae)
247 	void *h;
248 	struct audio_encoding *ae;
249 {
250 	int err = 0;
251 
252 	switch (ae->index) {
253 	case 0:
254 		strlcpy(ae->name, AudioEslinear, sizeof(ae->name));
255 		ae->encoding = AUDIO_ENCODING_SLINEAR;
256 		ae->precision = 16;
257 		ae->flags = 0;
258 		break;
259 	case 1:
260 		strlcpy(ae->name, AudioEslinear_be, sizeof(ae->name));
261 		ae->encoding = AUDIO_ENCODING_SLINEAR_BE;
262 		ae->precision = 16;
263 		ae->flags = 0;
264 		break;
265 	case 2:
266 		strlcpy(ae->name, AudioEslinear_le, sizeof(ae->name));
267 		ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
268 		ae->precision = 16;
269 		ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
270 		break;
271 	case 3:
272 		strlcpy(ae->name, AudioEulinear_be, sizeof(ae->name));
273 		ae->encoding = AUDIO_ENCODING_ULINEAR_BE;
274 		ae->precision = 16;
275 		ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
276 		break;
277 	case 4:
278 		strlcpy(ae->name, AudioEulinear_le, sizeof(ae->name));
279 		ae->encoding = AUDIO_ENCODING_ULINEAR_LE;
280 		ae->precision = 16;
281 		ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
282 		break;
283 	case 5:
284 		strlcpy(ae->name, AudioEmulaw, sizeof(ae->name));
285 		ae->encoding = AUDIO_ENCODING_ULAW;
286 		ae->precision = 8;
287 		ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
288 		break;
289 	case 6:
290 		strlcpy(ae->name, AudioEalaw, sizeof(ae->name));
291 		ae->encoding = AUDIO_ENCODING_ALAW;
292 		ae->precision = 8;
293 		ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
294 		break;
295 	case 7:
296 		strlcpy(ae->name, AudioEslinear, sizeof(ae->name));
297 		ae->encoding = AUDIO_ENCODING_SLINEAR;
298 		ae->precision = 8;
299 		ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
300 		break;
301 	case 8:
302 		strlcpy(ae->name, AudioEulinear, sizeof(ae->name));
303 		ae->encoding = AUDIO_ENCODING_ULINEAR;
304 		ae->precision = 8;
305 		ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
306 		break;
307 	default:
308 		err = EINVAL;
309 		break;
310 	}
311 	return (err);
312 }
313 
314 
315 struct i2s_mode {
316 	u_int encoding;
317 	u_int precision;
318 	u_int channels;
319 	void (*sw_code)(void *, u_char *, int);
320 	int factor;
321 } i2s_modes[] = {
322 	{ AUDIO_ENCODING_SLINEAR_LE,  8, 1, linear8_to_linear16_be_mts, 4 },
323 	{ AUDIO_ENCODING_SLINEAR_LE,  8, 2, linear8_to_linear16_be, 2 },
324 	{ AUDIO_ENCODING_SLINEAR_LE, 16, 1, swap_bytes_mts, 2 },
325 	{ AUDIO_ENCODING_SLINEAR_LE, 16, 2, swap_bytes, 1 },
326 	{ AUDIO_ENCODING_SLINEAR_BE,  8, 1, linear8_to_linear16_be_mts, 4 },
327 	{ AUDIO_ENCODING_SLINEAR_BE,  8, 2, linear8_to_linear16_be, 2 },
328 	{ AUDIO_ENCODING_SLINEAR_BE, 16, 1, noswap_bytes_mts, 2 },
329 	{ AUDIO_ENCODING_SLINEAR_BE, 16, 2, NULL, 1 },
330 	{ AUDIO_ENCODING_ULINEAR_LE,  8, 1, ulinear8_to_linear16_be_mts, 4 },
331 	{ AUDIO_ENCODING_ULINEAR_LE,  8, 2, ulinear8_to_linear16_be, 2 },
332 	{ AUDIO_ENCODING_ULINEAR_LE, 16, 1, change_sign16_swap_bytes_le_mts, 2 },
333 	{ AUDIO_ENCODING_ULINEAR_LE, 16, 2, swap_bytes_change_sign16_be, 1 },
334 	{ AUDIO_ENCODING_ULINEAR_BE,  8, 1, ulinear8_to_linear16_be_mts, 4 },
335 	{ AUDIO_ENCODING_ULINEAR_BE,  8, 2, ulinear8_to_linear16_be, 2 },
336 	{ AUDIO_ENCODING_ULINEAR_BE, 16, 1, change_sign16_be_mts, 2 },
337 	{ AUDIO_ENCODING_ULINEAR_BE, 16, 2, change_sign16_be, 1 }
338 };
339 
340 
341 struct i2s_mode *
342 i2s_find_mode(u_int encoding, u_int precision, u_int channels)
343 {
344 	struct i2s_mode *m;
345 	int i;
346 
347 	for (i = 0; i < sizeof(i2s_modes)/sizeof(i2s_modes[0]); i++) {
348 		m = &i2s_modes[i];
349 		if (m->encoding == encoding &&
350 		    m->precision == precision &&
351 		    m->channels == channels)
352 			return (m);
353 	}
354 	return (NULL);
355 }
356 
357 int
358 i2s_set_params(h, setmode, usemode, play, rec)
359 	void *h;
360 	int setmode, usemode;
361 	struct audio_params *play, *rec;
362 {
363 	struct i2s_mode *m;
364 	struct i2s_softc *sc = h;
365 	struct audio_params *p;
366 	int mode;
367 
368 	p = play; /* default to play */
369 
370 	/*
371 	 * This device only has one clock, so make the sample rates match.
372 	 */
373 	if (play->sample_rate != rec->sample_rate &&
374 	    usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
375 		if (setmode == AUMODE_PLAY) {
376 			rec->sample_rate = play->sample_rate;
377 			setmode |= AUMODE_RECORD;
378 		} else if (setmode == AUMODE_RECORD) {
379 			play->sample_rate = rec->sample_rate;
380 			setmode |= AUMODE_PLAY;
381 		} else
382 			return EINVAL;
383 	}
384 
385 	for (mode = AUMODE_RECORD; mode != -1;
386 	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
387 		if ((setmode & mode) == 0)
388 			continue;
389 
390 		p = mode == AUMODE_PLAY ? play : rec;
391 
392 		if (p->sample_rate < 4000)
393 			p->sample_rate = 4000;
394 		if (p->sample_rate > 50000)
395 			p->sample_rate = 50000;
396 		if (p->precision > 16)
397 			p->precision = 16;
398 		if (p->channels > 2)
399 			p->channels = 2;
400 
401 		switch (p->encoding) {
402 		case AUDIO_ENCODING_SLINEAR_LE:
403 		case AUDIO_ENCODING_SLINEAR_BE:
404 		case AUDIO_ENCODING_ULINEAR_LE:
405 		case AUDIO_ENCODING_ULINEAR_BE:
406 			m = i2s_find_mode(p->encoding, p->precision,
407 			    p->channels);
408 			if (m == NULL) {
409 				printf("mode not found: %u/%u/%u\n",
410 				    p->encoding, p->precision, p->channels);
411 				return (EINVAL);
412 			}
413 			p->factor = m->factor;
414 			p->sw_code = m->sw_code;
415 			break;
416 
417 		case AUDIO_ENCODING_ULAW:
418 			if (mode == AUMODE_PLAY) {
419 				if (p->channels == 1) {
420 					p->factor = 4;
421 					p->sw_code = mulaw_to_slinear16_be_mts;
422 					break;
423 				}
424 				if (p->channels == 2) {
425 					p->factor = 2;
426 					p->sw_code = mulaw_to_slinear16_be;
427 					break;
428 				}
429 			} else
430 				break; /* XXX */
431 			return (EINVAL);
432 
433 		case AUDIO_ENCODING_ALAW:
434 			if (mode == AUMODE_PLAY) {
435 				if (p->channels == 1) {
436 					p->factor = 4;
437 					p->sw_code = alaw_to_slinear16_be_mts;
438 					break;
439 				}
440 				if (p->channels == 2) {
441 					p->factor = 2;
442 					p->sw_code = alaw_to_slinear16_be;
443 					break;
444 				}
445 			} else
446 				break; /* XXX */
447 			return (EINVAL);
448 
449 		default:
450 			return (EINVAL);
451 		}
452 	}
453 
454 	/* Set the speed */
455 	if (i2s_set_rate(sc, play->sample_rate))
456 		return EINVAL;
457 
458 	p->sample_rate = sc->sc_rate;
459 
460 	return 0;
461 }
462 
463 void
464 i2s_get_default_params(struct audio_params *params)
465 {
466 	*params = i2s_audio_default;
467 }
468 
469 int
470 i2s_round_blocksize(h, size)
471 	void *h;
472 	int size;
473 {
474 	if (size < NBPG)
475 		size = NBPG;
476 	return size & ~PGOFSET;
477 }
478 
479 int
480 i2s_halt_output(h)
481 	void *h;
482 {
483 	struct i2s_softc *sc = h;
484 
485 	dbdma_stop(sc->sc_odma);
486 	dbdma_reset(sc->sc_odma);
487 	return 0;
488 }
489 
490 int
491 i2s_halt_input(h)
492 	void *h;
493 {
494 	struct i2s_softc *sc = h;
495 
496 	dbdma_stop(sc->sc_idma);
497 	dbdma_reset(sc->sc_idma);
498 	return 0;
499 }
500 
501 enum {
502 	I2S_OUTPUT_CLASS,
503 	I2S_RECORD_CLASS,
504 	I2S_OUTPUT_SELECT,
505 	I2S_VOL_OUTPUT,
506 	I2S_INPUT_SELECT,
507 	I2S_VOL_INPUT,
508 	I2S_BASS,
509 	I2S_TREBLE,
510 	I2S_ENUM_LAST
511 };
512 
513 int
514 i2s_set_port(h, mc)
515 	void *h;
516 	mixer_ctrl_t *mc;
517 {
518 	struct i2s_softc *sc = h;
519 	int l, r;
520 
521 	DPRINTF(("i2s_set_port dev = %d, type = %d\n", mc->dev, mc->type));
522 
523 	l = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
524 	r = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
525 
526 	switch (mc->dev) {
527 	case I2S_OUTPUT_SELECT:
528 		/* No change necessary? */
529 		if (mc->un.mask == sc->sc_output_mask)
530 			return 0;
531 
532 		i2s_mute_speaker(sc, 1);
533 		i2s_mute_headphone(sc, 1);
534 		i2s_mute_lineout(sc, 1);
535 		if (mc->un.mask & 1 << 0)
536 			i2s_mute_speaker(sc, 0);
537 		if (mc->un.mask & 1 << 1)
538 			i2s_mute_headphone(sc, 0);
539 		if (mc->un.mask & 1 << 2)
540 			i2s_mute_lineout(sc, 0);
541 
542 		sc->sc_output_mask = mc->un.mask;
543 		return 0;
544 
545 	case I2S_VOL_OUTPUT:
546 		(*sc->sc_setvolume)(sc, l, r);
547 		return 0;
548 
549 	case I2S_BASS:
550 		if (sc->sc_setbass != NULL)
551 			(*sc->sc_setbass)(sc, l);
552 		return (0);
553 
554 	case I2S_TREBLE:
555 		if (sc->sc_settreble != NULL)
556 			(*sc->sc_settreble)(sc, l);
557 		return (0);
558 
559 	case I2S_INPUT_SELECT:
560 		/* no change necessary? */
561 		if (mc->un.mask == sc->sc_record_source)
562 			return 0;
563 		switch (mc->un.mask) {
564 		case 1 << 0: /* microphone */
565 		case 1 << 1: /* line in */
566 			/* XXX TO BE DONE */
567 			break;
568 		default: /* invalid argument */
569 			return EINVAL;
570 		}
571 		if (sc->sc_setinput != NULL)
572 			(*sc->sc_setinput)(sc, mc->un.mask);
573 		sc->sc_record_source = mc->un.mask;
574 		return 0;
575 
576 	case I2S_VOL_INPUT:
577 		/* XXX TO BE DONE */
578 		return 0;
579 	}
580 
581 	return ENXIO;
582 }
583 
584 int
585 i2s_get_port(h, mc)
586 	void *h;
587 	mixer_ctrl_t *mc;
588 {
589 	struct i2s_softc *sc = h;
590 
591 	DPRINTF(("i2s_get_port dev = %d, type = %d\n", mc->dev, mc->type));
592 
593 	switch (mc->dev) {
594 	case I2S_OUTPUT_SELECT:
595 		mc->un.mask = sc->sc_output_mask;
596 		return 0;
597 
598 	case I2S_VOL_OUTPUT:
599 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = sc->sc_vol_l;
600 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = sc->sc_vol_r;
601 		return 0;
602 
603 	case I2S_INPUT_SELECT:
604 		mc->un.mask = sc->sc_record_source;
605 		return 0;
606 
607 	case I2S_BASS:
608 		if (mc->un.value.num_channels != 1)
609 			return ENXIO;
610 		mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_bass;
611 		return 0;
612 
613 	case I2S_TREBLE:
614 		if (mc->un.value.num_channels != 1)
615 			return ENXIO;
616 		mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_treble;
617 		return 0;
618 
619 	case I2S_VOL_INPUT:
620 		/* XXX TO BE DONE */
621 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 0;
622 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 0;
623 		return 0;
624 
625 	default:
626 		return ENXIO;
627 	}
628 
629 	return 0;
630 }
631 
632 int
633 i2s_query_devinfo(h, dip)
634 	void *h;
635 	mixer_devinfo_t *dip;
636 {
637 	struct i2s_softc *sc = h;
638 	int n = 0;
639 
640 	switch (dip->index) {
641 
642 	case I2S_OUTPUT_SELECT:
643 		dip->mixer_class = I2S_OUTPUT_CLASS;
644 		strlcpy(dip->label.name, AudioNselect, sizeof(dip->label.name));
645 		dip->type = AUDIO_MIXER_SET;
646 		dip->prev = dip->next = AUDIO_MIXER_LAST;
647 		strlcpy(dip->un.s.member[n].label.name, AudioNspeaker,
648 		    sizeof(dip->un.s.member[n].label.name));
649 		dip->un.s.member[n++].mask = 1 << 0;
650 		if (headphone_mute) {
651 			strlcpy(dip->un.s.member[n].label.name,
652 			    AudioNheadphone,
653 			    sizeof(dip->un.s.member[n].label.name));
654 			dip->un.s.member[n++].mask = 1 << 1;
655 		}
656 		if (lineout_mute) {
657 			strlcpy(dip->un.s.member[n].label.name,	AudioNline,
658 			    sizeof(dip->un.s.member[n].label.name));
659 			dip->un.s.member[n++].mask = 1 << 2;
660 		}
661 		dip->un.s.num_mem = n;
662 		return 0;
663 
664 	case I2S_VOL_OUTPUT:
665 		dip->mixer_class = I2S_OUTPUT_CLASS;
666 		strlcpy(dip->label.name, AudioNmaster, sizeof(dip->label.name));
667 		dip->type = AUDIO_MIXER_VALUE;
668 		dip->prev = dip->next = AUDIO_MIXER_LAST;
669 		dip->un.v.num_channels = 2;
670 		strlcpy(dip->un.v.units.name, AudioNvolume,
671 		    sizeof(dip->un.v.units.name));
672 		return 0;
673 
674 	case I2S_INPUT_SELECT:
675 		dip->mixer_class = I2S_RECORD_CLASS;
676 		strlcpy(dip->label.name, AudioNsource, sizeof(dip->label.name));
677 		dip->type = AUDIO_MIXER_SET;
678 		dip->prev = dip->next = AUDIO_MIXER_LAST;
679 		dip->un.s.num_mem = 2;
680 		strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone,
681 		    sizeof(dip->un.s.member[0].label.name));
682 		dip->un.s.member[0].mask = 1 << 0;
683 		strlcpy(dip->un.s.member[1].label.name, AudioNline,
684 		    sizeof(dip->un.s.member[1].label.name));
685 		dip->un.s.member[1].mask = 1 << 1;
686 		return 0;
687 
688 	case I2S_VOL_INPUT:
689 		dip->mixer_class = I2S_RECORD_CLASS;
690 		strlcpy(dip->label.name, AudioNrecord, sizeof(dip->label.name));
691 		dip->type = AUDIO_MIXER_VALUE;
692 		dip->prev = dip->next = AUDIO_MIXER_LAST;
693 		dip->un.v.num_channels = 2;
694 		strlcpy(dip->un.v.units.name, AudioNvolume,
695 		    sizeof(dip->un.v.units.name));
696 		return 0;
697 
698 	case I2S_OUTPUT_CLASS:
699 		dip->mixer_class = I2S_OUTPUT_CLASS;
700 		strlcpy(dip->label.name, AudioCoutputs,
701 		    sizeof(dip->label.name));
702 		dip->type = AUDIO_MIXER_CLASS;
703 		dip->next = dip->prev = AUDIO_MIXER_LAST;
704 		return 0;
705 
706 	case I2S_RECORD_CLASS:
707 		dip->mixer_class = I2S_RECORD_CLASS;
708 		strlcpy(dip->label.name, AudioCrecord, sizeof(dip->label.name));
709 		dip->type = AUDIO_MIXER_CLASS;
710 		dip->next = dip->prev = AUDIO_MIXER_LAST;
711 		return 0;
712 
713 	case I2S_BASS:
714 		if (sc->sc_setbass == NULL)
715 			return (ENXIO);
716 		dip->mixer_class = I2S_OUTPUT_CLASS;
717 		strlcpy(dip->label.name, AudioNbass, sizeof(dip->label.name));
718 		dip->type = AUDIO_MIXER_VALUE;
719 		dip->prev = dip->next = AUDIO_MIXER_LAST;
720 		dip->un.v.num_channels = 1;
721 		return (0);
722 
723 	case I2S_TREBLE:
724 		if (sc->sc_settreble == NULL)
725 			return (ENXIO);
726 		dip->mixer_class = I2S_OUTPUT_CLASS;
727 		strlcpy(dip->label.name, AudioNtreble, sizeof(dip->label.name));
728 		dip->type = AUDIO_MIXER_VALUE;
729 		dip->prev = dip->next = AUDIO_MIXER_LAST;
730 		dip->un.v.num_channels = 1;
731 		return (0);
732 	}
733 
734 	return ENXIO;
735 }
736 
737 size_t
738 i2s_round_buffersize(h, dir, size)
739 	void *h;
740 	int dir;
741 	size_t size;
742 {
743 	if (size > 65536)
744 		size = 65536;
745 	return size;
746 }
747 
748 paddr_t
749 i2s_mappage(h, mem, off, prot)
750 	void *h;
751 	void *mem;
752 	off_t off;
753 	int prot;
754 {
755 	if (off < 0)
756 		return -1;
757 	return -1;	/* XXX */
758 }
759 
760 int
761 i2s_get_props(h)
762 	void *h;
763 {
764 	return AUDIO_PROP_FULLDUPLEX /* | AUDIO_PROP_MMAP */;
765 }
766 
767 int
768 i2s_trigger_output(h, start, end, bsize, intr, arg, param)
769 	void *h;
770 	void *start, *end;
771 	int bsize;
772 	void (*intr)(void *);
773 	void *arg;
774 	struct audio_params *param;
775 {
776 	struct i2s_softc *sc = h;
777 	struct i2s_dma *p;
778 	struct dbdma_command *cmd = sc->sc_odmacmd;
779 	vaddr_t spa, pa, epa;
780 	int c;
781 
782 	DPRINTF(("trigger_output %p %p 0x%x\n", start, end, bsize));
783 
784 	for (p = sc->sc_dmas; p && p->addr != start; p = p->next);
785 	if (!p)
786 		return -1;
787 
788 	sc->sc_ointr = intr;
789 	sc->sc_oarg = arg;
790 	sc->sc_odmap = sc->sc_odmacmd;
791 
792 	spa = p->segs[0].ds_addr;
793 	c = DBDMA_CMD_OUT_MORE;
794 	for (pa = spa, epa = spa + (end - start);
795 	    pa < epa; pa += bsize, cmd++) {
796 
797 		if (pa + bsize == epa)
798 			c = DBDMA_CMD_OUT_LAST;
799 
800 		DBDMA_BUILD(cmd, c, 0, bsize, pa, DBDMA_INT_ALWAYS,
801 			DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
802 	}
803 
804 	DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0,
805 		DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS);
806 	dbdma_st32(&cmd->d_cmddep, sc->sc_odbdma->d_paddr);
807 
808 	dbdma_start(sc->sc_odma, sc->sc_odbdma);
809 
810 	return 0;
811 }
812 
813 int
814 i2s_trigger_input(h, start, end, bsize, intr, arg, param)
815 	void *h;
816 	void *start, *end;
817 	int bsize;
818 	void (*intr)(void *);
819 	void *arg;
820 	struct audio_params *param;
821 {
822 	struct i2s_softc *sc = h;
823 	struct i2s_dma *p;
824 	struct dbdma_command *cmd = sc->sc_idmacmd;
825 	vaddr_t spa, pa, epa;
826 	int c;
827 
828 	DPRINTF(("trigger_input %p %p 0x%x\n", start, end, bsize));
829 
830 	for (p = sc->sc_dmas; p && p->addr != start; p = p->next);
831 	if (!p)
832 		return -1;
833 
834 	sc->sc_iintr = intr;
835 	sc->sc_iarg = arg;
836 	sc->sc_idmap = sc->sc_idmacmd;
837 
838 	spa = p->segs[0].ds_addr;
839 	c = DBDMA_CMD_IN_MORE;
840 	for (pa = spa, epa = spa + (end - start);
841 	    pa < epa; pa += bsize, cmd++) {
842 
843 		if (pa + bsize == epa)
844 			c = DBDMA_CMD_IN_LAST;
845 
846 		DBDMA_BUILD(cmd, c, 0, bsize, pa, DBDMA_INT_ALWAYS,
847 			DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
848 	}
849 
850 	DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0,
851 		DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS);
852 	dbdma_st32(&cmd->d_cmddep, sc->sc_idbdma->d_paddr);
853 
854 	dbdma_start(sc->sc_idma, sc->sc_idbdma);
855 
856 	return 0;
857 }
858 
859 
860 /* rate = fs = LRCLK
861  * SCLK = 64*LRCLK (I2S)
862  * MCLK = 256fs (typ. -- changeable)
863  * MCLK = clksrc / mdiv
864  *  SCLK = MCLK / sdiv
865  * rate = SCLK / 64    ( = LRCLK = fs)
866  */
867 int
868 i2s_set_rate(sc, rate)
869 	struct i2s_softc *sc;
870 	int rate;
871 {
872 	u_int reg = 0;
873 	int MCLK;
874 	int clksrc, mdiv, sdiv;
875 	int mclk_fs;
876 	int timo;
877 
878 	/* sanify */
879 	if (rate > (48000 + 44100) / 2)
880 		rate = 48000;
881 	else
882 		rate = 44100;
883 
884 	switch (rate) {
885 	case 44100:
886 		clksrc = 45158400;		/* 45MHz */
887 		reg = CLKSRC_45MHz;
888 		mclk_fs = 256;
889 		break;
890 
891 	case 48000:
892 		clksrc = 49152000;		/* 49MHz */
893 		reg = CLKSRC_49MHz;
894 		mclk_fs = 256;
895 		break;
896 
897 	default:
898 		return EINVAL;
899 	}
900 
901 	MCLK = rate * mclk_fs;
902 	mdiv = clksrc / MCLK;			/* 4 */
903 	sdiv = mclk_fs / 64;			/* 4 */
904 
905 	switch (mdiv) {
906 	case 1:
907 		reg |= MCLK_DIV1;
908 		break;
909 	case 3:
910 		reg |= MCLK_DIV3;
911 		break;
912 	case 5:
913 		reg |= MCLK_DIV5;
914 		break;
915 	default:
916 		reg |= ((mdiv / 2 - 1) << 24) & 0x1f000000;
917 		break;
918 	}
919 
920 	switch (sdiv) {
921 	case 1:
922 		reg |= SCLK_DIV1;
923 		break;
924 	case 3:
925 		reg |= SCLK_DIV3;
926 		break;
927 	default:
928 		reg |= ((sdiv / 2 - 1) << 20) & 0x00f00000;
929 		break;
930 	}
931 
932 	reg |= SCLK_MASTER;	/* XXX master mode */
933 
934 	reg |= SERIAL_64x;
935 
936 	if (sc->sc_rate == rate)
937 		return (0);
938 
939 	/* stereo input and output */
940 	DPRINTF(("I2SSetDataWordSizeReg 0x%08x -> 0x%08x\n",
941 	    in32rb(sc->sc_reg + I2S_WORDSIZE), 0x02000200));
942 	out32rb(sc->sc_reg + I2S_WORDSIZE, 0x02000200);
943 
944 	/* Clear CLKSTOPPEND */
945 	out32rb(sc->sc_reg + I2S_INT, I2S_INT_CLKSTOPPEND);
946 
947 	keylargo_fcr_disable(I2SClockOffset, I2S0CLKEN);
948 
949 	/* Wait until clock is stopped */
950 	for (timo = 50; timo > 0; timo--) {
951 		if (in32rb(sc->sc_reg + I2S_INT) & I2S_INT_CLKSTOPPEND)
952 			goto done;
953 		delay(10);
954 	}
955 
956 	printf("i2s_set_rate: timeout\n");
957 
958 done:
959 	DPRINTF(("I2SSetSerialFormatReg 0x%x -> 0x%x\n",
960 	    in32rb(sc->sc_reg + I2S_FORMAT), reg));
961 	out32rb(sc->sc_reg + I2S_FORMAT, reg);
962 
963 	keylargo_fcr_enable(I2SClockOffset, I2S0CLKEN);
964 
965 	sc->sc_rate = rate;
966 
967 	return 0;
968 }
969 
970 int
971 gpio_read(addr)
972 	char *addr;
973 {
974 	if (*addr & GPIO_DATA)
975 		return 1;
976 	return 0;
977 }
978 
979 void
980 gpio_write(addr, val)
981 	char *addr;
982 	int val;
983 {
984 	u_int data = GPIO_DDR_OUTPUT;
985 
986 	if (val)
987 		data |= GPIO_DATA;
988 	*addr = data;
989 	asm volatile ("eieio" ::: "memory");
990 }
991 
992 #define amp_active 0		/* XXX OF */
993 #define headphone_active 0	/* XXX OF */
994 #define lineout_active 0	/* XXX OF */
995 
996 void
997 i2s_mute_speaker(sc, mute)
998 	struct i2s_softc *sc;
999 	int mute;
1000 {
1001 	u_int x;
1002 
1003 	if (amp_mute == NULL)
1004 		return;
1005 
1006 	DPRINTF(("ampmute %d --> ", gpio_read(amp_mute)));
1007 
1008 	if (mute)
1009 		x = amp_active;		/* mute */
1010 	else
1011 		x = !amp_active;	/* unmute */
1012 	if (x != gpio_read(amp_mute))
1013 		gpio_write(amp_mute, x);
1014 
1015 	DPRINTF(("%d\n", gpio_read(amp_mute)));
1016 }
1017 
1018 void
1019 i2s_mute_headphone(sc, mute)
1020 	struct i2s_softc *sc;
1021 	int mute;
1022 {
1023 	u_int x;
1024 
1025 	if (headphone_mute == NULL)
1026 		return;
1027 
1028 	DPRINTF(("headphonemute %d --> ", gpio_read(headphone_mute)));
1029 
1030 	if (mute)
1031 		x = headphone_active;	/* mute */
1032 	else
1033 		x = !headphone_active;	/* unmute */
1034 	if (x != gpio_read(headphone_mute))
1035 		gpio_write(headphone_mute, x);
1036 
1037 	DPRINTF(("%d\n", gpio_read(headphone_mute)));
1038 }
1039 
1040 void
1041 i2s_mute_lineout(sc, mute)
1042 	struct i2s_softc *sc;
1043 	int mute;
1044 {
1045 	u_int x;
1046 
1047 	if (lineout_mute == NULL)
1048 		return;
1049 
1050 	DPRINTF(("lineout %d --> ", gpio_read(lineout_mute)));
1051 
1052 	if (mute)
1053 		x = lineout_active;	/* mute */
1054 	else
1055 		x = !lineout_active;	/* unmute */
1056 	if (x != gpio_read(lineout_mute))
1057 		gpio_write(lineout_mute, x);
1058 
1059 	DPRINTF(("%d\n", gpio_read(lineout_mute)));
1060 }
1061 
1062 int
1063 i2s_cint(v)
1064 	void *v;
1065 {
1066 	struct i2s_softc *sc = v;
1067 	u_int sense;
1068 
1069 	sc->sc_output_mask = 0;
1070 	i2s_mute_speaker(sc, 1);
1071 	i2s_mute_headphone(sc, 1);
1072 	i2s_mute_lineout(sc, 1);
1073 
1074 	if (headphone_detect)
1075 		sense = *headphone_detect;
1076 	else
1077 		sense = !headphone_detect_active << 1;
1078 	DPRINTF(("headphone detect = 0x%x\n", sense));
1079 
1080 	if (((sense & 0x02) >> 1) == headphone_detect_active) {
1081 		DPRINTF(("headphone is inserted\n"));
1082 		sc->sc_output_mask |= 1 << 1;
1083 		i2s_mute_headphone(sc, 0);
1084 	} else {
1085 		DPRINTF(("headphone is NOT inserted\n"));
1086 	}
1087 
1088 	if (lineout_detect)
1089 		sense = *lineout_detect;
1090 	else
1091 		sense = !lineout_detect_active << 1;
1092 	DPRINTF(("lineout detect = 0x%x\n", sense));
1093 
1094 	if (((sense & 0x02) >> 1) == lineout_detect_active) {
1095 		DPRINTF(("lineout is inserted\n"));
1096 		sc->sc_output_mask |= 1 << 2;
1097 		i2s_mute_lineout(sc, 0);
1098 	} else {
1099 		DPRINTF(("lineout is NOT inserted\n"));
1100 	}
1101 
1102 	if (sc->sc_output_mask == 0) {
1103 		sc->sc_output_mask |= 1 << 0;
1104 		i2s_mute_speaker(sc, 0);
1105 	}
1106 
1107 	return 1;
1108 }
1109 
1110 u_char *
1111 i2s_gpio_map(struct i2s_softc *sc, char *name, int *irq)
1112 {
1113 	u_int32_t reg[2];
1114 	u_int32_t intr[2];
1115 	int gpio;
1116 
1117 	if (OF_getprop(sc->sc_node, name, &gpio,
1118             sizeof(gpio)) != sizeof(gpio) ||
1119 	    OF_getprop(gpio, "reg", &reg[0],
1120 	    sizeof(reg[0])) != sizeof(reg[0]) ||
1121 	    OF_getprop(OF_parent(gpio), "reg", &reg[1],
1122 	    sizeof(reg[1])) != sizeof(reg[1]))
1123 		return NULL;
1124 
1125 	if (irq && OF_getprop(gpio, "interrupts",
1126 	    intr, sizeof(intr)) == sizeof(intr)) {
1127 		*irq = intr[0];
1128 	}
1129 
1130 	return mapiodev(sc->sc_baseaddr + reg[0] + reg[1], 1);
1131 }
1132 
1133 void
1134 i2s_gpio_init(sc, node, parent)
1135 	struct i2s_softc *sc;
1136 	int node;
1137 	struct device *parent;
1138 {
1139 	int gpio;
1140 	int headphone_detect_intr = -1, headphone_detect_intrtype;
1141 	int lineout_detect_intr = -1;
1142 
1143 	/* Map gpios. */
1144 	amp_mute = i2s_gpio_map(sc, "platform-amp-mute", NULL);
1145 	headphone_mute = i2s_gpio_map(sc, "platform-headphone-mute", NULL);
1146 	headphone_detect = i2s_gpio_map(sc, "platform-headphone-detect",
1147 	    &headphone_detect_intr);
1148 	lineout_mute = i2s_gpio_map(sc, "platform-lineout-mute", NULL);
1149 	lineout_detect = i2s_gpio_map(sc, "platform-lineout-detect",
1150 	    &lineout_detect_intr);
1151 	audio_hw_reset = i2s_gpio_map(sc, "platform-hw-reset", NULL);
1152 
1153 	gpio = OF_getnodebyname(OF_parent(node), "gpio");
1154 	DPRINTF((" /gpio 0x%x\n", gpio));
1155 	gpio = OF_child(gpio);
1156 	while (gpio) {
1157 		char name[64], audio_gpio[64];
1158 		int intr[2];
1159 		paddr_t addr;
1160 
1161 		bzero(name, sizeof name);
1162 		bzero(audio_gpio, sizeof audio_gpio);
1163 		addr = 0;
1164 		OF_getprop(gpio, "name", name, sizeof name);
1165 		OF_getprop(gpio, "audio-gpio", audio_gpio, sizeof audio_gpio);
1166 		OF_getprop(gpio, "AAPL,address", &addr, sizeof addr);
1167 		/* printf("0x%x %s %s\n", gpio, name, audio_gpio); */
1168 
1169 		/* gpio5 */
1170 		if (headphone_mute == NULL &&
1171 		    strcmp(audio_gpio, "headphone-mute") == 0)
1172 			headphone_mute = mapiodev(addr,1);
1173 
1174 		/* gpio6 */
1175 		if (amp_mute == NULL &&
1176 		    strcmp(audio_gpio, "amp-mute") == 0)
1177 			amp_mute = mapiodev(addr,1);
1178 
1179 		/* extint-gpio15 */
1180 		if (headphone_detect == NULL &&
1181 		    strcmp(audio_gpio, "headphone-detect") == 0) {
1182 			headphone_detect = mapiodev(addr,1);
1183 			OF_getprop(gpio, "audio-gpio-active-state",
1184 			    &headphone_detect_active, 4);
1185 			OF_getprop(gpio, "interrupts", intr, 8);
1186 			headphone_detect_intr = intr[0];
1187 			headphone_detect_intrtype = intr[1];
1188 		}
1189 
1190 		/* gpio11 (keywest-11) */
1191 		if (audio_hw_reset == NULL &&
1192 		    strcmp(audio_gpio, "audio-hw-reset") == 0)
1193 			audio_hw_reset = mapiodev(addr,1);
1194 
1195 		gpio = OF_peer(gpio);
1196 	}
1197 	DPRINTF((" amp-mute %p\n", amp_mute));
1198 	DPRINTF((" headphone-mute %p\n", headphone_mute));
1199 	DPRINTF((" headphone-detect %p\n", headphone_detect));
1200 	DPRINTF((" headphone-detect active %x\n", headphone_detect_active));
1201 	DPRINTF((" headphone-detect intr %x\n", headphone_detect_intr));
1202 	DPRINTF((" lineout-mute %p\n", lineout_mute));
1203 	DPRINTF((" lineout-detect %p\n", lineout_detect));
1204 	DPRINTF((" lineout-detect active %x\n", lineout_detect_active));
1205 	DPRINTF((" lineout-detect intr %x\n", lineout_detect_intr));
1206 	DPRINTF((" audio-hw-reset %p\n", audio_hw_reset));
1207 
1208 	if (headphone_detect_intr != -1)
1209 		mac_intr_establish(parent, headphone_detect_intr, IST_EDGE,
1210 		    IPL_AUDIO, i2s_cint, sc, sc->sc_dev.dv_xname);
1211 
1212 	if (lineout_detect_intr != -1)
1213 		mac_intr_establish(parent, lineout_detect_intr, IST_EDGE,
1214 		    IPL_AUDIO, i2s_cint, sc, sc->sc_dev.dv_xname);
1215 
1216 	/* Enable headphone interrupt? */
1217 	*headphone_detect |= 0x80;
1218 	asm volatile("eieio");
1219 
1220 	/* Update headphone status. */
1221 	i2s_cint(sc);
1222 }
1223 
1224 void *
1225 i2s_allocm(void *h, int dir, size_t size, int type, int flags)
1226 {
1227 	struct i2s_softc *sc = h;
1228 	struct i2s_dma *p;
1229 	int error;
1230 
1231 	if (size > I2S_DMALIST_MAX * I2S_DMASEG_MAX)
1232 		return (NULL);
1233 
1234 	p = malloc(sizeof(*p), type, flags | M_ZERO);
1235 	if (!p)
1236 		return (NULL);
1237 
1238 	/* convert to the bus.h style, not used otherwise */
1239 	if (flags & M_NOWAIT)
1240 		flags = BUS_DMA_NOWAIT;
1241 
1242 	p->size = size;
1243 	if ((error = bus_dmamem_alloc(sc->sc_dmat, p->size, NBPG, 0, p->segs,
1244 	    1, &p->nsegs, flags)) != 0) {
1245 		printf("%s: unable to allocate dma, error = %d\n",
1246 		    sc->sc_dev.dv_xname, error);
1247 		free(p, type);
1248 		return NULL;
1249 	}
1250 
1251 	if ((error = bus_dmamem_map(sc->sc_dmat, p->segs, p->nsegs, p->size,
1252 	    &p->addr, flags | BUS_DMA_COHERENT)) != 0) {
1253 		printf("%s: unable to map dma, error = %d\n",
1254 		    sc->sc_dev.dv_xname, error);
1255 		bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
1256 		free(p, type);
1257 		return NULL;
1258 	}
1259 
1260 	if ((error = bus_dmamap_create(sc->sc_dmat, p->size, 1,
1261 	    p->size, 0, flags, &p->map)) != 0) {
1262 		printf("%s: unable to create dma map, error = %d\n",
1263 		    sc->sc_dev.dv_xname, error);
1264 		bus_dmamem_unmap(sc->sc_dmat, p->addr, size);
1265 		bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
1266 		free(p, type);
1267 		return NULL;
1268 	}
1269 
1270 	if ((error = bus_dmamap_load(sc->sc_dmat, p->map, p->addr, p->size,
1271 	    NULL, flags)) != 0) {
1272 		printf("%s: unable to load dma map, error = %d\n",
1273 		    sc->sc_dev.dv_xname, error);
1274 		bus_dmamap_destroy(sc->sc_dmat, p->map);
1275 		bus_dmamem_unmap(sc->sc_dmat, p->addr, size);
1276 		bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
1277 		free(p, type);
1278 		return NULL;
1279 	}
1280 
1281 	p->next = sc->sc_dmas;
1282 	sc->sc_dmas = p;
1283 
1284 	return p->addr;
1285 }
1286 
1287 #define reset_active 0
1288 
1289 int
1290 deq_reset(struct i2s_softc *sc)
1291 {
1292 	if (audio_hw_reset == NULL)
1293 		return (-1);
1294 
1295 	gpio_write(audio_hw_reset, !reset_active);
1296 	delay(1000000);
1297 
1298 	gpio_write(audio_hw_reset, reset_active);
1299 	delay(1);
1300 
1301 	gpio_write(audio_hw_reset, !reset_active);
1302 	delay(10000);
1303 
1304 	return (0);
1305 }
1306