xref: /openbsd-src/sys/dev/pci/auixp.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /* $OpenBSD: auixp.c,v 1.29 2011/07/03 15:47:16 matthew Exp $ */
2 /* $NetBSD: auixp.c,v 1.9 2005/06/27 21:13:09 thorpej Exp $ */
3 
4 /*
5  * Copyright (c) 2004, 2005 Reinoud Zandijk <reinoud@netbsd.org>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the NetBSD
18  *	Foundation, Inc. and its contributors.
19  * 4. Neither the name of The NetBSD Foundation nor the names of its
20  *    contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 /*
36  * Audio driver for ATI IXP-{150,200,...} audio driver hardware.
37  *
38  * Recording and playback has been tested OK on various sample rates and
39  * encodings.
40  *
41  * Known problems and issues :
42  * - SPDIF is untested and needs some work still (LED stays off)
43  * - 32 bit audio playback failed last time i tried but that might an AC'97
44  *   codec support problem.
45  * - 32 bit recording works but can't try out playing: see above.
46  * - no suspend/resume support yet.
47  * - multiple codecs are `supported' but not tested; the implemetation needs
48  *   some cleaning up.
49  */
50 
51 /*#define DEBUG_AUIXP*/
52 
53 #include <sys/types.h>
54 #include <sys/errno.h>
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/malloc.h>
58 #include <sys/device.h>
59 #include <sys/conf.h>
60 #include <sys/exec.h>
61 #include <sys/selinfo.h>
62 #include <sys/audioio.h>
63 #include <sys/queue.h>
64 
65 #include <machine/bus.h>
66 #include <machine/intr.h>
67 
68 #include <dev/pci/pcidevs.h>
69 #include <dev/pci/pcivar.h>
70 
71 #include <dev/audio_if.h>
72 #include <dev/mulaw.h>
73 #include <dev/auconv.h>
74 #include <dev/ic/ac97.h>
75 
76 #include <dev/pci/auixpreg.h>
77 #include <dev/pci/auixpvar.h>
78 
79 /* codec detection constant indicating the interrupt flags */
80 #define ALL_CODECS_NOT_READY \
81     (ATI_REG_ISR_CODEC0_NOT_READY | ATI_REG_ISR_CODEC1_NOT_READY |\
82      ATI_REG_ISR_CODEC2_NOT_READY)
83 #define CODEC_CHECK_BITS (ALL_CODECS_NOT_READY|ATI_REG_ISR_NEW_FRAME)
84 
85 /* why isn't this base address register not in the headerfile? */
86 #define PCI_CBIO 0x10
87 
88 /* macro's used */
89 #define KERNADDR(p)	((void *)((p)->addr))
90 #define	DMAADDR(p)	((p)->map->dm_segs[0].ds_addr)
91 
92 const struct pci_matchid auixp_pci_devices[] = {
93 	{ PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB200_AUDIO },
94 	{ PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB300_AUDIO },
95 	{ PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB400_AUDIO },
96 	{ PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB600_AUDIO }
97 };
98 
99 struct cfdriver auixp_cd = {
100 	NULL, "auixp", DV_DULL
101 };
102 
103 int	auixp_match( struct device *, void *, void *);
104 void	auixp_attach(struct device *, struct device *, void *);
105 int	auixp_detach(struct device *, int);
106 
107 int	auixp_activate(struct device *, int);
108 
109 struct cfattach auixp_ca = {
110 	sizeof(struct auixp_softc), auixp_match, auixp_attach,
111 	NULL, auixp_activate
112 };
113 
114 int	auixp_open(void *v, int flags);
115 void	auixp_close(void *v);
116 int	auixp_query_encoding(void *, struct audio_encoding *);
117 int	auixp_set_params(void *, int, int, struct audio_params *,
118     struct audio_params *);
119 int	auixp_commit_settings(void *);
120 int	auixp_round_blocksize(void *, int);
121 int	auixp_trigger_output(void *, void *, void *, int,
122     void (*)(void *), void *, struct audio_params *);
123 int	auixp_trigger_input(void *, void *, void *, int,
124     void (*)(void *), void *, struct audio_params *);
125 int	auixp_halt_output(void *);
126 int	auixp_halt_input(void *);
127 int	auixp_set_port(void *, mixer_ctrl_t *);
128 int	auixp_get_port(void *, mixer_ctrl_t *);
129 int	auixp_query_devinfo(void *, mixer_devinfo_t *);
130 void *	auixp_malloc(void *, int, size_t, int, int);
131 void	auixp_free(void *, void *, int);
132 int	auixp_getdev(void *, struct audio_device *);
133 size_t	auixp_round_buffersize(void *, int, size_t);
134 int	auixp_get_props(void *);
135 int	auixp_intr(void *);
136 int	auixp_allocmem(struct auixp_softc *, size_t, size_t,
137     struct auixp_dma *);
138 int	auixp_freemem(struct auixp_softc *, struct auixp_dma *);
139 paddr_t	auixp_mappage(void *, void *, off_t, int);
140 void	auixp_get_default_params(void *, int, struct audio_params *);
141 
142 /* Supporting subroutines */
143 int	auixp_init(struct auixp_softc *);
144 void	auixp_autodetect_codecs(struct auixp_softc *);
145 void	auixp_post_config(void *);
146 
147 void	auixp_reset_aclink(struct auixp_softc *);
148 int	auixp_attach_codec(void *, struct ac97_codec_if *);
149 int	auixp_read_codec(void *, u_int8_t, u_int16_t *);
150 int	auixp_write_codec(void *, u_int8_t, u_int16_t);
151 int	auixp_wait_for_codecs(struct auixp_softc *, const char *);
152 void	auixp_reset_codec(void *);
153 enum ac97_host_flags	auixp_flags_codec(void *);
154 
155 void	auixp_enable_dma(struct auixp_softc *, struct auixp_dma *);
156 void	auixp_disable_dma(struct auixp_softc *, struct auixp_dma *);
157 void	auixp_enable_interrupts(struct auixp_softc *);
158 void	auixp_disable_interrupts(struct auixp_softc *);
159 
160 void	auixp_link_daisychain(struct auixp_softc *,
161     struct auixp_dma *, struct auixp_dma *, int, int);
162 int	auixp_allocate_dma_chain(struct auixp_softc *, struct auixp_dma **);
163 void	auixp_program_dma_chain(struct auixp_softc *, struct auixp_dma *);
164 void	auixp_dma_update(struct auixp_softc *, struct auixp_dma *);
165 void	auixp_update_busbusy(struct auixp_softc *);
166 
167 #ifdef DEBUG_AUIXP
168 #define DPRINTF(x)	printf x;
169 #else
170 #define DPRINTF(x)
171 #endif
172 
173 struct audio_hw_if auixp_hw_if = {
174 	auixp_open,
175 	auixp_close,
176 	NULL,			/* drain */
177 	auixp_query_encoding,
178 	auixp_set_params,
179 	auixp_round_blocksize,
180 	auixp_commit_settings,
181 	NULL,			/* init_output  */
182 	NULL,			/* init_input   */
183 	NULL,			/* start_output */
184 	NULL,			/* start_input  */
185 	auixp_halt_output,
186 	auixp_halt_input,
187 	NULL,			/* speaker_ctl */
188 	auixp_getdev,
189 	NULL,			/* getfd */
190 	auixp_set_port,
191 	auixp_get_port,
192 	auixp_query_devinfo,
193 	auixp_malloc,
194 	auixp_free,
195 	auixp_round_buffersize,
196 	auixp_mappage,
197 	auixp_get_props,
198 	auixp_trigger_output,
199 	auixp_trigger_input,
200 	auixp_get_default_params
201 };
202 
203 int
204 auixp_open(void *v, int flags)
205 {
206 
207 	return 0;
208 }
209 
210 void
211 auixp_close(void *v)
212 {
213 }
214 
215 void
216 auixp_get_default_params(void *v, int mode, struct audio_params *params)
217 {
218 	ac97_get_default_params(params);
219 }
220 
221 int
222 auixp_query_encoding(void *hdl, struct audio_encoding *aep)
223 {
224 	switch (aep->index) {
225 	case 0:
226 		strlcpy(aep->name, AudioEulinear, sizeof aep->name);
227 		aep->encoding = AUDIO_ENCODING_ULINEAR;
228 		aep->precision = 8;
229 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
230 		break;
231 	case 1:
232 		strlcpy(aep->name, AudioEmulaw, sizeof aep->name);
233 		aep->encoding = AUDIO_ENCODING_ULAW;
234 		aep->precision = 8;
235 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
236 		break;
237 	case 2:
238 		strlcpy(aep->name, AudioEalaw, sizeof aep->name);
239 		aep->encoding = AUDIO_ENCODING_ALAW;
240 		aep->precision = 8;
241 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
242 		break;
243 	case 3:
244 		strlcpy(aep->name, AudioEslinear, sizeof aep->name);
245 		aep->encoding = AUDIO_ENCODING_SLINEAR;
246 		aep->precision = 8;
247 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
248 		break;
249 	case 4:
250 		strlcpy(aep->name, AudioEslinear_le, sizeof aep->name);
251 		aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
252 		aep->precision = 16;
253 		aep->flags = 0;
254 		break;
255 	case 5:
256 		strlcpy(aep->name, AudioEulinear_le, sizeof aep->name);
257 		aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
258 		aep->precision = 16;
259 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
260 		break;
261 	case 6:
262 		strlcpy(aep->name, AudioEslinear_be, sizeof aep->name);
263 		aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
264 		aep->precision = 16;
265 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
266 		break;
267 	case 7:
268 		strlcpy(aep->name, AudioEulinear_be, sizeof aep->name);
269 		aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
270 		aep->precision = 16;
271 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
272 		break;
273 	default:
274 		return (EINVAL);
275 	}
276 	aep->bps = AUDIO_BPS(aep->precision);
277 	aep->msb = 1;
278 
279 	return (0);
280 }
281 
282 
283 /* commit setting and program ATI IXP chip */
284 int
285 auixp_commit_settings(void *hdl)
286 {
287 	struct auixp_codec *co;
288 	struct auixp_softc *sc;
289 	bus_space_tag_t    iot;
290 	bus_space_handle_t ioh;
291 	struct audio_params *params;
292 	u_int32_t value;
293 
294 	/* XXX would it be better to stop interrupts first? XXX */
295 	co = (struct auixp_codec *) hdl;
296 	sc = co->sc;
297 	iot = sc->sc_iot;
298 	ioh = sc->sc_ioh;
299 
300 	/* process input settings */
301 	params = &sc->sc_play_params;
302 
303 	/* set input interleaving (precision) */
304 	value  =  bus_space_read_4(iot, ioh, ATI_REG_CMD);
305 	value &= ~ATI_REG_CMD_INTERLEAVE_IN;
306 	if (params->precision <= 16)
307 		value |= ATI_REG_CMD_INTERLEAVE_IN;
308 	bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
309 
310 	/* process output settings */
311 	params = &sc->sc_play_params;
312 
313 	value  =  bus_space_read_4(iot, ioh, ATI_REG_OUT_DMA_SLOT);
314 	value &= ~ATI_REG_OUT_DMA_SLOT_MASK;
315 
316 	/* TODO SPDIF case for 8 channels */
317 	switch (params->channels) {
318 	case 6:
319 		value |= ATI_REG_OUT_DMA_SLOT_BIT(7) |
320 			 ATI_REG_OUT_DMA_SLOT_BIT(8);
321 		/* FALLTHROUGH */
322 	case 4:
323 		value |= ATI_REG_OUT_DMA_SLOT_BIT(6) |
324 			 ATI_REG_OUT_DMA_SLOT_BIT(9);
325 		/* FALLTHROUGH */
326 	default:
327 		value |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
328 			 ATI_REG_OUT_DMA_SLOT_BIT(4);
329 		break;
330 	}
331 	/* set output threshold */
332 	value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
333 	bus_space_write_4(iot, ioh, ATI_REG_OUT_DMA_SLOT, value);
334 
335 	/* set output interleaving (precision) */
336 	value  =  bus_space_read_4(iot, ioh, ATI_REG_CMD);
337 	value &= ~ATI_REG_CMD_INTERLEAVE_OUT;
338 	if (params->precision <= 16)
339 		value |= ATI_REG_CMD_INTERLEAVE_OUT;
340 	bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
341 
342 	/* enable 6 channel reordering */
343 	value  =  bus_space_read_4(iot, ioh, ATI_REG_6CH_REORDER);
344 	value &= ~ATI_REG_6CH_REORDER_EN;
345 	if (params->channels == 6)
346 		value |= ATI_REG_6CH_REORDER_EN;
347 	bus_space_write_4(iot, ioh, ATI_REG_6CH_REORDER, value);
348 
349 	if (sc->has_spdif) {
350 		/* set SPDIF (if present) */
351 		value  =  bus_space_read_4(iot, ioh, ATI_REG_CMD);
352 		value &= ~ATI_REG_CMD_SPDF_CONFIG_MASK;
353 		value |=  ATI_REG_CMD_SPDF_CONFIG_34; /* NetBSD AC'97 default */
354 
355 		/* XXX this is probably not necessary unless splitted XXX */
356 		value &= ~ATI_REG_CMD_INTERLEAVE_SPDF;
357 		if (params->precision <= 16)
358 			value |= ATI_REG_CMD_INTERLEAVE_SPDF;
359 		bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
360 	}
361 
362 	return 0;
363 }
364 
365 
366 /* set audio properties in desired setting */
367 int
368 auixp_set_params(void *hdl, int setmode, int usemode,
369     struct audio_params *play, struct audio_params *rec)
370 {
371 	struct auixp_codec *co;
372 	int error;
373 	u_int temprate;
374 
375 	co = (struct auixp_codec *) hdl;
376 	if (setmode & AUMODE_PLAY) {
377 		play->factor = 1;
378 		play->sw_code = NULL;
379 		if (play->channels > 2)
380 			play->channels = 2;
381 		if (play->precision > 16)
382 			play->precision = 16;
383 		switch(play->encoding) {
384 		case AUDIO_ENCODING_ULAW:
385 			switch (play->channels) {
386 			case 1:
387 				play->factor = 4;
388 				play->sw_code = mulaw_to_slinear16_le_mts;
389 				break;
390 			case 2:
391 				play->factor = 2;
392 				play->sw_code = mulaw_to_slinear16_le;
393 				break;
394 			default:
395 				return (EINVAL);
396 			}
397 			break;
398 		case AUDIO_ENCODING_SLINEAR_LE:
399 			switch (play->precision) {
400 			case 8:
401 				switch (play->channels) {
402 				case 1:
403 					play->factor = 4;
404 					play->sw_code = linear8_to_linear16_le_mts;
405 					break;
406 				case 2:
407 					play->factor = 2;
408 					play->sw_code = linear8_to_linear16_le;
409 					break;
410 				default:
411 					return (EINVAL);
412 				}
413 				break;
414 			case 16:
415 				switch (play->channels) {
416 				case 1:
417 					play->factor = 2;
418 					play->sw_code = noswap_bytes_mts;
419 					break;
420 				case 2:
421 					break;
422 				default:
423 					return (EINVAL);
424 				}
425 				break;
426 			default:
427 				return (EINVAL);
428 			}
429 			break;
430 		case AUDIO_ENCODING_ULINEAR_LE:
431 			switch (play->precision) {
432 			case 8:
433 				switch (play->channels) {
434 				case 1:
435 					play->factor = 4;
436 					play->sw_code = ulinear8_to_linear16_le_mts;
437 					break;
438 				case 2:
439 					play->factor = 2;
440 					play->sw_code = ulinear8_to_linear16_le;
441 					break;
442 				default:
443 					return (EINVAL);
444 				}
445 				break;
446 			case 16:
447 				switch (play->channels) {
448 				case 1:
449 					play->factor = 2;
450 					play->sw_code = change_sign16_le_mts;
451 					break;
452 				case 2:
453 					play->sw_code = change_sign16_le;
454 					break;
455 				default:
456 					return (EINVAL);
457 				}
458 				break;
459 			default:
460 				return (EINVAL);
461 			}
462 			break;
463 		case AUDIO_ENCODING_ALAW:
464 			switch (play->channels) {
465 			case 1:
466 				play->factor = 4;
467 				play->sw_code = alaw_to_slinear16_le_mts;
468 				break;
469 			case 2:
470 				play->factor = 2;
471 				play->sw_code = alaw_to_slinear16_le;
472 				break;
473 			default:
474 				return (EINVAL);
475 			}
476 			break;
477 		case AUDIO_ENCODING_SLINEAR_BE:
478 			switch (play->precision) {
479 			case 8:
480 				switch (play->channels) {
481 				case 1:
482 					play->factor = 4;
483 					play->sw_code = linear8_to_linear16_le_mts;
484 					break;
485 				case 2:
486 					play->factor = 2;
487 					play->sw_code = linear8_to_linear16_le;
488 					break;
489 				default:
490 					return (EINVAL);
491 				}
492 				break;
493 			case 16:
494 				switch (play->channels) {
495 				case 1:
496 					play->factor = 2;
497 					play->sw_code = swap_bytes_mts;
498 					break;
499 				case 2:
500 					play->sw_code = swap_bytes;
501 					break;
502 				default:
503 					return (EINVAL);
504 				}
505 				break;
506 			default:
507 				return (EINVAL);
508 			}
509 			break;
510 		case AUDIO_ENCODING_ULINEAR_BE:
511 			switch (play->precision) {
512 			case 8:
513 				switch (play->channels) {
514 				case 1:
515 					play->factor = 4;
516 					play->sw_code = ulinear8_to_linear16_le_mts;
517 					break;
518 				case 2:
519 					play->factor = 2;
520 					play->sw_code = ulinear8_to_linear16_le;
521 					break;
522 				default:
523 					return (EINVAL);
524 				}
525 				break;
526 			case 16:
527 				switch (play->channels) {
528 				case 1:
529 					play->factor = 2;
530 					play->sw_code = swap_bytes_change_sign16_le_mts;
531 					break;
532 				case 2:
533 					play->sw_code = swap_bytes_change_sign16_le;
534 					break;
535 				default:
536 					return (EINVAL);
537 				}
538 				break;
539 			default:
540 				return (EINVAL);
541 			}
542 			break;
543 		default:
544 			return (EINVAL);
545 		}
546 		play->bps = AUDIO_BPS(play->precision);
547 		play->msb = 1;
548 
549 		temprate = play->sample_rate;
550 		error = ac97_set_rate(co->codec_if,
551 		    AC97_REG_PCM_LFE_DAC_RATE, &play->sample_rate);
552 		if (error)
553 			return (error);
554 
555 		play->sample_rate = temprate;
556 		error = ac97_set_rate(co->codec_if,
557 		    AC97_REG_PCM_SURR_DAC_RATE, &play->sample_rate);
558 		if (error)
559 			return (error);
560 
561 		play->sample_rate = temprate;
562 		error = ac97_set_rate(co->codec_if,
563 		    AC97_REG_PCM_FRONT_DAC_RATE, &play->sample_rate);
564 		if (error)
565 			return (error);
566 
567 	}
568 
569 	if (setmode & AUMODE_RECORD) {
570 		rec->factor = 1;
571 		rec->sw_code = 0;
572 		if (rec->channels > 2)
573 			rec->channels = 2;
574 		if (rec->precision > 16)
575 			rec->precision = 16;
576 		switch(rec->encoding) {
577 		case AUDIO_ENCODING_ULAW:
578 			rec->sw_code = ulinear8_to_mulaw;
579 			break;
580 		case AUDIO_ENCODING_SLINEAR_LE:
581 			if (rec->precision == 8)
582 				rec->sw_code = change_sign8;
583 			break;
584 		case AUDIO_ENCODING_ULINEAR_LE:
585 			if (rec->precision == 16)
586 				rec->sw_code = change_sign16_le;
587 			break;
588 		case AUDIO_ENCODING_ALAW:
589 			rec->sw_code = ulinear8_to_alaw;
590 			break;
591 		case AUDIO_ENCODING_SLINEAR_BE:
592 			if (rec->precision == 16)
593 				rec->sw_code = swap_bytes;
594 			else
595 				rec->sw_code = change_sign8;
596 			break;
597 		case AUDIO_ENCODING_ULINEAR_BE:
598 			if (rec->precision == 16)
599 				rec->sw_code = swap_bytes_change_sign16_le;
600 			break;
601 		default:
602 			return (EINVAL);
603 		}
604 		rec->bps = AUDIO_BPS(rec->precision);
605 		rec->msb = 1;
606 
607 		error = ac97_set_rate(co->codec_if, AC97_REG_PCM_LR_ADC_RATE,
608 		    &rec->sample_rate);
609 		if (error)
610 			return (error);
611 	}
612 
613 	return (0);
614 }
615 
616 
617 /* called to translate a requested blocksize to a hw-possible one */
618 int
619 auixp_round_blocksize(void *v, int blk)
620 {
621 
622 	blk = (blk + 0x1f) & ~0x1f;
623 	/* Be conservative; align to 32 bytes and maximise it to 64 kb */
624 	if (blk > 0x10000)
625 		blk = 0x10000;
626 
627 	return blk;
628 }
629 
630 
631 /*
632  * allocate dma capable memory and record its information for later retrieval
633  * when we program the dma chain itself. The trigger routines passes on the
634  * kernel virtual address we return here as a reference to the mapping.
635  */
636 void *
637 auixp_malloc(void *hdl, int direction, size_t size, int pool, int flags)
638 {
639 	struct auixp_codec *co;
640 	struct auixp_softc *sc;
641 	struct auixp_dma *dma;
642 	int error;
643 
644 	co = (struct auixp_codec *) hdl;
645 	sc = co->sc;
646 	/* get us a auixp_dma structure */
647 	dma = malloc(sizeof(*dma), pool, flags);
648 	if (!dma)
649 		return NULL;
650 
651 	/* get us a dma buffer itself */
652 	error = auixp_allocmem(sc, size, 16, dma);
653 	if (error) {
654 		free(dma, pool);
655 		printf("%s: auixp_malloc: not enough memory\n",
656 		    sc->sc_dev.dv_xname);
657 		return NULL;
658 	}
659 	SLIST_INSERT_HEAD(&sc->sc_dma_list, dma, dma_chain);
660 
661 	DPRINTF(("auixp_malloc: returning kern %p,   hw 0x%08x for %d bytes "
662 	    "in %d segs\n", KERNADDR(dma), (u_int32_t) DMAADDR(dma), dma->size,
663 	    dma->nsegs)
664 	);
665 
666 	return KERNADDR(dma);
667 }
668 
669 /*
670  * free and release dma capable memory we allocated before and remove its
671  * recording
672  */
673 void
674 auixp_free(void *hdl, void *addr, int pool)
675 {
676 	struct auixp_codec *co;
677 	struct auixp_softc *sc;
678 	struct auixp_dma *dma;
679 
680 	co = (struct auixp_codec *) hdl;
681 	sc = co->sc;
682 	SLIST_FOREACH(dma, &sc->sc_dma_list, dma_chain) {
683 		if (KERNADDR(dma) == addr) {
684 			SLIST_REMOVE(&sc->sc_dma_list, dma, auixp_dma,
685 			    dma_chain);
686 			auixp_freemem(sc, dma);
687 			free(dma, pool);
688 			return;
689 		}
690 	}
691 }
692 
693 int
694 auixp_getdev(void *v, struct audio_device *adp)
695 {
696 	struct auixp_softc *sc = v;
697 	*adp = sc->sc_audev;
698 	return 0;
699 }
700 
701 /* pass request to AC'97 codec code */
702 int
703 auixp_set_port(void *hdl, mixer_ctrl_t *mc)
704 {
705 	struct auixp_codec *co;
706 
707 	co = (struct auixp_codec *) hdl;
708 	return co->codec_if->vtbl->mixer_set_port(co->codec_if, mc);
709 }
710 
711 
712 /* pass request to AC'97 codec code */
713 int
714 auixp_get_port(void *hdl, mixer_ctrl_t *mc)
715 {
716 	struct auixp_codec *co;
717 
718 	co = (struct auixp_codec *) hdl;
719 	return co->codec_if->vtbl->mixer_get_port(co->codec_if, mc);
720 }
721 
722 /* pass request to AC'97 codec code */
723 int
724 auixp_query_devinfo(void *hdl, mixer_devinfo_t *di)
725 {
726 	struct auixp_codec *co;
727 
728 	co = (struct auixp_codec *) hdl;
729 	return co->codec_if->vtbl->query_devinfo(co->codec_if, di);
730 }
731 
732 
733 size_t
734 auixp_round_buffersize(void *hdl, int direction, size_t bufsize)
735 {
736 
737 	/* XXX force maximum? i.e. 256 kb? */
738 	return bufsize;
739 }
740 
741 
742 int
743 auixp_get_props(void *hdl)
744 {
745 
746 	return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
747 }
748 
749 
750 /*
751  * A dma descriptor has dma->nsegs segments defined in dma->segs set up when
752  * we claimed the memory.
753  *
754  * Due to our demand for one contiguous DMA area, we only have one segment. A
755  * c_dma structure is about 3 kb for the 256 entries we maximally program
756  * -arbitrary limit AFAIK- so all is most likely to be in one segment/page
757  * anyway.
758  *
759  * XXX ought to implement fragmented dma area XXX
760  *
761  * Note that _v variables depict kernel virtual addresses, _p variables depict
762  * physical addresses.
763  */
764 void
765 auixp_link_daisychain(struct auixp_softc *sc,
766 		struct auixp_dma *c_dma, struct auixp_dma *s_dma,
767 		int blksize, int blocks)
768 {
769 	atiixp_dma_desc_t *caddr_v, *next_caddr_v;
770 	u_int32_t caddr_p, next_caddr_p, saddr_p;
771 	int i;
772 
773 	/* just make sure we are not changing when its running */
774 	auixp_disable_dma(sc, c_dma);
775 
776 	/* setup dma chain start addresses */
777 	caddr_v = KERNADDR(c_dma);
778 	caddr_p = DMAADDR(c_dma);
779 	saddr_p = DMAADDR(s_dma);
780 
781 	/* program the requested number of blocks */
782 	for (i = 0; i < blocks; i++) {
783 		/* clear the block just in case */
784 		bzero(caddr_v, sizeof(atiixp_dma_desc_t));
785 
786 		/* round robin the chain dma addresses for its successor */
787 		next_caddr_v = caddr_v + 1;
788 		next_caddr_p = caddr_p + sizeof(atiixp_dma_desc_t);
789 
790 		if (i == blocks-1) {
791 			next_caddr_v = KERNADDR(c_dma);
792 			next_caddr_p = DMAADDR(c_dma);
793 		}
794 
795 		/* fill in the hardware dma chain descriptor in little-endian */
796 		caddr_v->addr   = htole32(saddr_p);
797 		caddr_v->status = htole16(0);
798 		caddr_v->size   = htole16((blksize >> 2)); /* in dwords (!!!) */
799 		caddr_v->next   = htole32(next_caddr_p);
800 
801 		/* advance slot */
802 		saddr_p += blksize;	/* XXX assuming contiguous XXX */
803 		caddr_v  = next_caddr_v;
804 		caddr_p  = next_caddr_p;
805 	}
806 }
807 
808 
809 int
810 auixp_allocate_dma_chain(struct auixp_softc *sc, struct auixp_dma **dmap)
811 {
812 	struct auixp_dma *dma;
813 	int error;
814 
815 	/* allocate keeper of dma area */
816 	*dmap = NULL;
817 	dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT | M_ZERO);
818 	if (!dma)
819 		return ENOMEM;
820 
821 	/* allocate for daisychain of IXP hardware-dma descriptors */
822 	error = auixp_allocmem(sc, DMA_DESC_CHAIN * sizeof(atiixp_dma_desc_t),
823 	    16, dma);
824 	if (error) {
825 		printf("%s: can't malloc dma descriptor chain\n",
826 		    sc->sc_dev.dv_xname);
827 		free(dma, M_DEVBUF);
828 		return ENOMEM;
829 	}
830 
831 	/* return info and initialise structure */
832 	dma->intr    = NULL;
833 	dma->intrarg = NULL;
834 
835 	*dmap = dma;
836 	return 0;
837 }
838 
839 
840 /* program dma chain in its link address descriptor */
841 void
842 auixp_program_dma_chain(struct auixp_softc *sc, struct auixp_dma *dma)
843 {
844 	bus_space_tag_t    iot;
845 	bus_space_handle_t ioh;
846 	u_int32_t value;
847 
848 	iot = sc->sc_iot;
849 	ioh = sc->sc_ioh;
850 	/* get hardware start address of DMA chain and set valid-flag in it */
851 	/* XXX always at start? XXX */
852 	value = DMAADDR(dma);
853 	value = value | ATI_REG_LINKPTR_EN;
854 
855 	/* reset linkpointer */
856 	bus_space_write_4(iot, ioh, dma->linkptr, 0);
857 
858 	/* reset this DMA engine */
859 	auixp_disable_dma(sc, dma);
860 	auixp_enable_dma(sc, dma);
861 
862 	/* program new DMA linkpointer */
863 	bus_space_write_4(iot, ioh, dma->linkptr, value);
864 }
865 
866 
867 /* called from interrupt code to signal end of one dma-slot */
868 void
869 auixp_dma_update(struct auixp_softc *sc, struct auixp_dma *dma)
870 {
871 
872 	/* be very paranoid */
873 	if (!dma)
874 		panic("auixp: update: dma = NULL");
875 	if (!dma->intr)
876 		panic("auixp: update: dma->intr = NULL");
877 
878 	/* request more input from upper layer */
879 	(*dma->intr)(dma->intrarg);
880 }
881 
882 
883 /*
884  * The magic `busbusy' bit that needs to be set when dma is active; allowing
885  * busmastering?
886  */
887 void
888 auixp_update_busbusy(struct auixp_softc *sc)
889 {
890 	bus_space_tag_t    iot;
891 	bus_space_handle_t ioh;
892 	u_int32_t value;
893 	int running;
894 
895 	iot = sc->sc_iot;
896 	ioh = sc->sc_ioh;
897 	/* set bus-busy flag when either recording or playing is performed */
898 	value  = bus_space_read_4(iot, ioh, ATI_REG_IER);
899 	value &= ~ATI_REG_IER_SET_BUS_BUSY;
900 
901 	running = ((sc->sc_output_dma->running) || (sc->sc_input_dma->running));
902 	if (running)
903 		value |= ATI_REG_IER_SET_BUS_BUSY;
904 
905 	bus_space_write_4(iot, ioh, ATI_REG_IER, value);
906 
907 }
908 
909 
910 /*
911  * Called from upper audio layer to request playing audio, only called once;
912  * audio is refilled by calling the intr() function when space is available
913  * again.
914  */
915 /* XXX almost literally a copy of trigger-input; could be factorised XXX */
916 int
917 auixp_trigger_output(void *hdl, void *start, void *end, int blksize,
918     void (*intr)(void *), void *intrarg, struct audio_params *param)
919 {
920 	struct auixp_codec *co;
921 	struct auixp_softc *sc;
922 	struct auixp_dma   *chain_dma;
923 	struct auixp_dma   *sound_dma;
924 	u_int32_t blocks;
925 
926 	co = (struct auixp_codec *) hdl;
927 	sc = co->sc;
928 	chain_dma = sc->sc_output_dma;
929 	/* add functions to call back */
930 	chain_dma->intr    = intr;
931 	chain_dma->intrarg = intrarg;
932 
933 	/*
934 	 * Program output DMA chain with blocks from [start...end] with
935 	 * blksize fragments.
936 	 *
937 	 * NOTE, we can assume its in one block since we asked for it to be in
938 	 * one contiguous blob; XXX change this? XXX
939 	 */
940 	blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize;
941 
942 	/* lookup `start' address in our list of DMA area's */
943 	SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) {
944 		if (KERNADDR(sound_dma) == start)
945 			break;
946 	}
947 
948 	/* not ours ? then bail out */
949 	if (!sound_dma) {
950 		printf("%s: auixp_trigger_output: bad sound addr %p\n",
951 		    sc->sc_dev.dv_xname, start);
952 		return EINVAL;
953 	}
954 
955 	/* link round-robin daisychain and program hardware */
956 	auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks);
957 	auixp_program_dma_chain(sc, chain_dma);
958 
959 	/* mark we are now able to run now */
960 	chain_dma->running = 1;
961 
962 	/* update bus-flags; XXX programs more flags XXX */
963 	auixp_update_busbusy(sc);
964 
965 	/* callbacks happen in interrupt routine */
966 	return 0;
967 }
968 
969 
970 /* halt output of audio, just disable its dma and update bus state */
971 int
972 auixp_halt_output(void *hdl)
973 {
974 	struct auixp_codec *co;
975 	struct auixp_softc *sc;
976 	struct auixp_dma   *dma;
977 
978 	co  = (struct auixp_codec *) hdl;
979 	sc  = co->sc;
980 	dma = sc->sc_output_dma;
981 	auixp_disable_dma(sc, dma);
982 
983 	dma->running = 0;
984 	auixp_update_busbusy(sc);
985 
986 	return 0;
987 }
988 
989 
990 /* XXX almost literally a copy of trigger-output; could be factorised XXX */
991 int
992 auixp_trigger_input(void *hdl, void *start, void *end, int blksize,
993     void (*intr)(void *), void *intrarg, struct audio_params *param)
994 {
995 	struct auixp_codec *co;
996 	struct auixp_softc *sc;
997 	struct auixp_dma   *chain_dma;
998 	struct auixp_dma   *sound_dma;
999 	u_int32_t blocks;
1000 
1001 	co = (struct auixp_codec *) hdl;
1002 	sc = co->sc;
1003 	chain_dma = sc->sc_input_dma;
1004 	/* add functions to call back */
1005 	chain_dma->intr    = intr;
1006 	chain_dma->intrarg = intrarg;
1007 
1008 	/*
1009 	 * Program output DMA chain with blocks from [start...end] with
1010 	 * blksize fragments.
1011 	 *
1012 	 * NOTE, we can assume its in one block since we asked for it to be in
1013 	 * one contiguous blob; XXX change this? XXX
1014 	 */
1015 	blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize;
1016 
1017 	/* lookup `start' address in our list of DMA area's */
1018 	SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) {
1019 		if (KERNADDR(sound_dma) == start)
1020 			break;
1021 	}
1022 
1023 	/* not ours ? then bail out */
1024 	if (!sound_dma) {
1025 		printf("%s: auixp_trigger_input: bad sound addr %p\n",
1026 		    sc->sc_dev.dv_xname, start);
1027 		return EINVAL;
1028 	}
1029 
1030 	/* link round-robin daisychain and program hardware */
1031 	auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks);
1032 	auixp_program_dma_chain(sc, chain_dma);
1033 
1034 	/* mark we are now able to run now */
1035 	chain_dma->running = 1;
1036 
1037 	/* update bus-flags; XXX programs more flags XXX */
1038 	auixp_update_busbusy(sc);
1039 
1040 	/* callbacks happen in interrupt routine */
1041 	return 0;
1042 }
1043 
1044 
1045 /* halt sampling audio, just disable its dma and update bus state */
1046 int
1047 auixp_halt_input(void *hdl)
1048 {
1049 	struct auixp_codec *co;
1050 	struct auixp_softc *sc;
1051 	struct auixp_dma   *dma;
1052 
1053 	co = (struct auixp_codec *) hdl;
1054 	sc = co->sc;
1055 	dma = sc->sc_input_dma;
1056 	auixp_disable_dma(sc, dma);
1057 
1058 	dma->running = 0;
1059 	auixp_update_busbusy(sc);
1060 
1061 	return 0;
1062 }
1063 
1064 
1065 /*
1066  * IXP audio interrupt handler
1067  *
1068  * note that we return the number of bits handled; the return value is not
1069  * documented but I saw it implemented in other drivers. Probably returning a
1070  * value > 0 means "I've dealt with it"
1071  *
1072  */
1073 int
1074 auixp_intr(void *softc)
1075 {
1076 	struct auixp_softc *sc;
1077 	bus_space_tag_t    iot;
1078 	bus_space_handle_t ioh;
1079 	u_int32_t status, enable, detected_codecs;
1080 	int ret;
1081 
1082 	sc = softc;
1083 	iot = sc->sc_iot;
1084 	ioh = sc->sc_ioh;
1085 	ret = 0;
1086 	/* get status from the interrupt status register */
1087 	status = bus_space_read_4(iot, ioh, ATI_REG_ISR);
1088 
1089 	if (status == 0)
1090 		return 0;
1091 
1092 	DPRINTF(("%s: (status = %x)\n", sc->sc_dev.dv_xname, status));
1093 
1094 	/* check DMA UPDATE flags for input & output */
1095 	if (status & ATI_REG_ISR_IN_STATUS) {
1096 		ret++; DPRINTF(("IN_STATUS\n"));
1097 		auixp_dma_update(sc, sc->sc_input_dma);
1098 	}
1099 	if (status & ATI_REG_ISR_OUT_STATUS) {
1100 		ret++; DPRINTF(("OUT_STATUS\n"));
1101 		auixp_dma_update(sc, sc->sc_output_dma);
1102 	}
1103 
1104 	/* XXX XRUN flags not used/needed yet; should i implement it? XXX */
1105 	/* acknowledge the interrupts nevertheless */
1106 	if (status & ATI_REG_ISR_IN_XRUN) {
1107 		ret++; DPRINTF(("IN_XRUN\n"));
1108 		/* auixp_dma_xrun(sc, sc->sc_input_dma);  */
1109 	}
1110 	if (status & ATI_REG_ISR_OUT_XRUN) {
1111 		ret++; DPRINTF(("OUT_XRUN\n"));
1112 		/* auixp_dma_xrun(sc, sc->sc_output_dma); */
1113 	}
1114 
1115 	/* check if we are looking for codec detection */
1116 	if (status & CODEC_CHECK_BITS) {
1117 		ret++;
1118 		/* mark missing codecs as not ready */
1119 		detected_codecs = status & CODEC_CHECK_BITS;
1120 		sc->sc_codec_not_ready_bits |= detected_codecs;
1121 
1122 		/* disable detected interrupt sources */
1123 		enable  = bus_space_read_4(iot, ioh, ATI_REG_IER);
1124 		enable &= ~detected_codecs;
1125 		bus_space_write_4(iot, ioh, ATI_REG_IER, enable);
1126 	}
1127 
1128 	/* acknowledge interrupt sources */
1129 	bus_space_write_4(iot, ioh, ATI_REG_ISR, status);
1130 
1131 	return ret;
1132 }
1133 
1134 
1135 /* allocate memory for dma purposes; on failure of any of the steps, roll back */
1136 int
1137 auixp_allocmem(struct auixp_softc *sc, size_t size,
1138 	       size_t align, struct auixp_dma *dma)
1139 {
1140 	int error;
1141 
1142 	/* remember size */
1143 	dma->size = size;
1144 
1145 	/* allocate DMA safe memory but in just one segment for now :( */
1146 	error = bus_dmamem_alloc(sc->sc_dmat, dma->size, align, 0,
1147 	    dma->segs, sizeof(dma->segs) / sizeof(dma->segs[0]), &dma->nsegs,
1148 	    BUS_DMA_NOWAIT);
1149 	if (error)
1150 		return error;
1151 
1152 	/*
1153 	 * map allocated memory into kernel virtual address space and keep it
1154 	 * coherent with the CPU.
1155 	 */
1156 	error = bus_dmamem_map(sc->sc_dmat, dma->segs, dma->nsegs, dma->size,
1157 				&dma->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
1158 	if (error)
1159 		goto free;
1160 
1161 	/* allocate associated dma handle and initialize it. */
1162 	error = bus_dmamap_create(sc->sc_dmat, dma->size, 1, dma->size, 0,
1163 				  BUS_DMA_NOWAIT, &dma->map);
1164 	if (error)
1165 		goto unmap;
1166 
1167 	/*
1168 	 * load the dma handle with mappings for a dma transfer; all pages
1169 	 * need to be wired.
1170 	 */
1171 	error = bus_dmamap_load(sc->sc_dmat, dma->map, dma->addr, dma->size, NULL,
1172 				BUS_DMA_NOWAIT);
1173 	if (error)
1174 		goto destroy;
1175 
1176 	return 0;
1177 
1178 destroy:
1179 	bus_dmamap_destroy(sc->sc_dmat, dma->map);
1180 unmap:
1181 	bus_dmamem_unmap(sc->sc_dmat, dma->addr, dma->size);
1182 free:
1183 	bus_dmamem_free(sc->sc_dmat, dma->segs, dma->nsegs);
1184 
1185 	return error;
1186 }
1187 
1188 
1189 /* undo dma mapping and release memory allocated */
1190 int
1191 auixp_freemem(struct auixp_softc *sc, struct auixp_dma *p)
1192 {
1193 
1194 	bus_dmamap_unload(sc->sc_dmat, p->map);
1195 	bus_dmamap_destroy(sc->sc_dmat, p->map);
1196 	bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size);
1197 	bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
1198 
1199 	return 0;
1200 }
1201 
1202 
1203 /* memory map dma memory */
1204 paddr_t
1205 auixp_mappage(void *hdl, void *mem, off_t off, int prot)
1206 {
1207 	struct auixp_codec *co;
1208 	struct auixp_softc *sc;
1209 	struct auixp_dma *p;
1210 
1211 	co = (struct auixp_codec *) hdl;
1212 	sc  = co->sc;
1213 	/* for sanity */
1214 	if (off < 0)
1215 		return -1;
1216 
1217 	/* look up allocated DMA area */
1218 	SLIST_FOREACH(p, &sc->sc_dma_list, dma_chain) {
1219 		if (KERNADDR(p) == mem)
1220 			break;
1221 	}
1222 
1223 	/* have we found it ? */
1224 	if (!p)
1225 		return -1;
1226 
1227 	/* return mmap'd region */
1228 	return bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nsegs,
1229 	    off, prot, BUS_DMA_WAITOK);
1230 }
1231 
1232 int
1233 auixp_match(struct device *dev, void *match, void *aux)
1234 {
1235 	return (pci_matchbyid((struct pci_attach_args *)aux, auixp_pci_devices,
1236 	    sizeof(auixp_pci_devices)/sizeof(auixp_pci_devices[0])));
1237 }
1238 
1239 int
1240 auixp_activate(struct device *self, int act)
1241 {
1242 	struct auixp_softc *sc = (struct auixp_softc *)self;
1243 	int rv = 0;
1244 
1245 	switch (act) {
1246 	case DVACT_QUIESCE:
1247 		rv = config_activate_children(self, act);
1248 		break;
1249 	case DVACT_SUSPEND:
1250 		auixp_disable_interrupts(sc);
1251 		break;
1252 	case DVACT_RESUME:
1253 		auixp_init(sc);
1254 		ac97_resume(&sc->sc_codec.host_if, sc->sc_codec.codec_if);
1255 		rv = config_activate_children(self, act);
1256 		break;
1257 	case DVACT_DEACTIVATE:
1258 		break;
1259 	}
1260 	return (rv);
1261 }
1262 
1263 void
1264 auixp_attach(struct device *parent, struct device *self, void *aux)
1265 {
1266 	struct auixp_softc *sc;
1267 	struct pci_attach_args *pa;
1268 	pcitag_t tag;
1269 	pci_chipset_tag_t pc;
1270 	pci_intr_handle_t ih;
1271 	const char *intrstr;
1272 
1273 	sc = (struct auixp_softc *)self;
1274 	pa = (struct pci_attach_args *)aux;
1275 	tag = pa->pa_tag;
1276 	pc = pa->pa_pc;
1277 
1278 	/* map memory; its not sized -> what is the size? max PCI slot size? */
1279 	if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_MEM, 0,
1280 	    &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios, 0)) {
1281 		printf(": can't map mem space\n");
1282 		return;
1283 	}
1284 
1285 	/* Initialize softc */
1286 	sc->sc_tag = tag;
1287 	sc->sc_pct = pc;
1288 	sc->sc_dmat = pa->pa_dmat;
1289 	SLIST_INIT(&sc->sc_dma_list);
1290 
1291 	/* get us the auixp_dma structures */
1292 	auixp_allocate_dma_chain(sc, &sc->sc_output_dma);
1293 	auixp_allocate_dma_chain(sc, &sc->sc_input_dma);
1294 
1295 	/* when that fails we are dead in the water */
1296 	if (!sc->sc_output_dma || !sc->sc_input_dma)
1297 		return;
1298 
1299 #if 0
1300 	/* could preliminary program DMA chain */
1301 	auixp_program_dma_chain(sc, sc->sc_output_dma);
1302 	auixp_program_dma_chain(sc, sc->sc_input_dma);
1303 #endif
1304 
1305 	if (pci_intr_map(pa, &ih)) {
1306 		printf(": can't map interrupt\n");
1307 		return;
1308 	}
1309 	intrstr = pci_intr_string(pc, ih);
1310 	sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, auixp_intr, sc,
1311 	    sc->sc_dev.dv_xname);
1312 	if (sc->sc_ih == NULL) {
1313 		printf(": can't establish interrupt");
1314 		if (intrstr != NULL)
1315 			printf(" at %s", intrstr);
1316 		printf("\n");
1317 		return;
1318 	}
1319 	printf(": %s\n", intrstr);
1320 
1321 	strlcpy(sc->sc_audev.name, "ATI IXP AC97", sizeof sc->sc_audev.name);
1322 	snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version, "0x%02x",
1323 	    PCI_REVISION(pa->pa_class));
1324 	strlcpy(sc->sc_audev.config, sc->sc_dev.dv_xname,
1325 	    sizeof sc->sc_audev.config);
1326 
1327 	/* power up chip */
1328 	pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D0);
1329 
1330 	/* init chip */
1331 	if (auixp_init(sc) == -1) {
1332 		printf("%s: auixp_attach: unable to initialize the card\n",
1333 		    sc->sc_dev.dv_xname);
1334 		return;
1335 	}
1336 
1337 	/*
1338 	 * delay further configuration of codecs and audio after interrupts
1339 	 * are enabled.
1340 	 */
1341 	mountroothook_establish(auixp_post_config, self);
1342 }
1343 
1344 /* called from autoconfigure system when interrupts are enabled */
1345 void
1346 auixp_post_config(void *self)
1347 {
1348 	struct auixp_softc *sc;
1349 
1350 	sc = (struct auixp_softc *)self;
1351 	/* detect the AC97 codecs */
1352 	auixp_autodetect_codecs(sc);
1353 
1354 	/* Bail if no codecs attached. */
1355 	if (!sc->sc_codec.present) {
1356 		printf("%s: no codecs detected or initialised\n",
1357 		    sc->sc_dev.dv_xname);
1358 		return;
1359 	}
1360 
1361 	audio_attach_mi(&auixp_hw_if, &sc->sc_codec, &sc->sc_dev);
1362 
1363 #if notyet
1364 	/* copy formats and invalidate entries not suitable for codec0 */
1365 	sc->has_4ch   = AC97_IS_4CH(sc->sc_codec.codec_if);
1366 	sc->has_6ch   = AC97_IS_6CH(sc->sc_codec.codec_if);
1367 	sc->is_fixed  = AC97_IS_FIXED_RATE(sc->sc_codec.codec_if);
1368 	sc->has_spdif = AC97_HAS_SPDIF(sc->sc_codec.codec_if);
1369 #endif
1370 
1371 	if (sc->has_spdif)
1372 		sc->has_spdif = 0;
1373 
1374 	/* fill in the missing details about the dma channels. */
1375 	/* for output */
1376 	sc->sc_output_dma->linkptr        = ATI_REG_OUT_DMA_LINKPTR;
1377 	sc->sc_output_dma->dma_enable_bit = ATI_REG_CMD_OUT_DMA_EN |
1378 					    ATI_REG_CMD_SEND_EN;
1379 	/* have spdif? then this too! XXX not seeing LED yet! XXX */
1380 	if (sc->has_spdif)
1381 		sc->sc_output_dma->dma_enable_bit |= ATI_REG_CMD_SPDF_OUT_EN;
1382 
1383 	/* and for input */
1384 	sc->sc_input_dma->linkptr         = ATI_REG_IN_DMA_LINKPTR;
1385 	sc->sc_input_dma->dma_enable_bit  = ATI_REG_CMD_IN_DMA_EN  |
1386 					    ATI_REG_CMD_RECEIVE_EN;
1387 
1388 	/* done! now enable all interrupts we can service */
1389 	auixp_enable_interrupts(sc);
1390 }
1391 
1392 void
1393 auixp_enable_interrupts(struct auixp_softc *sc)
1394 {
1395 	bus_space_tag_t     iot;
1396 	bus_space_handle_t  ioh;
1397 	u_int32_t value;
1398 
1399 	iot = sc->sc_iot;
1400 	ioh = sc->sc_ioh;
1401 	/* clear all pending */
1402 	bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff);
1403 
1404 	/* enable all relevant interrupt sources we can handle */
1405 	value = bus_space_read_4(iot, ioh, ATI_REG_IER);
1406 
1407 	value |= ATI_REG_IER_IO_STATUS_EN;
1408 #ifdef notyet
1409 	value |= ATI_REG_IER_IN_XRUN_EN;
1410 	value |= ATI_REG_IER_OUT_XRUN_EN;
1411 
1412 	value |= ATI_REG_IER_SPDIF_XRUN_EN;
1413 	value |= ATI_REG_IER_SPDF_STATUS_EN;
1414 #endif
1415 
1416 	bus_space_write_4(iot, ioh, ATI_REG_IER, value);
1417 }
1418 
1419 void
1420 auixp_disable_interrupts(struct auixp_softc *sc)
1421 {
1422 	bus_space_tag_t     iot;
1423 	bus_space_handle_t  ioh;
1424 
1425 	iot = sc->sc_iot;
1426 	ioh = sc->sc_ioh;
1427 	/* disable all interrupt sources */
1428 	bus_space_write_4(iot, ioh, ATI_REG_IER, 0);
1429 
1430 	/* clear all pending */
1431 	bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff);
1432 }
1433 
1434 /* dismantle what we've set up by undoing setup */
1435 int
1436 auixp_detach(struct device *self, int flags)
1437 {
1438 	struct auixp_softc *sc;
1439 
1440 	sc = (struct auixp_softc *)self;
1441 	/* XXX shouldn't we just reset the chip? XXX */
1442 	/*
1443 	 * should we explicitly disable interrupt generation and acknowledge
1444 	 * what's left on? better be safe than sorry.
1445 	 */
1446 	auixp_disable_interrupts(sc);
1447 
1448 	/* tear down .... */
1449 	config_detach(&sc->sc_dev, flags);	/* XXX OK? XXX */
1450 
1451 	if (sc->sc_ih != NULL)
1452 		pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
1453 	if (sc->sc_ios)
1454 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
1455 	return 0;
1456 }
1457 
1458 
1459 /*
1460  * codec handling
1461  *
1462  * IXP audio support can have upto 3 codecs! are they chained ? or
1463  * alternative outlets with the same audio feed i.e. with different mixer
1464  * settings? XXX does NetBSD support more than one audio codec? XXX
1465  */
1466 
1467 
1468 int
1469 auixp_attach_codec(void *aux, struct ac97_codec_if *codec_if)
1470 {
1471 	struct auixp_codec *ixp_codec;
1472 
1473 	ixp_codec = aux;
1474 	ixp_codec->codec_if = codec_if;
1475 
1476 	return 0;
1477 }
1478 
1479 int
1480 auixp_read_codec(void *aux, u_int8_t reg, u_int16_t *result)
1481 {
1482 	struct auixp_codec *co;
1483 	struct auixp_softc *sc;
1484 	bus_space_tag_t     iot;
1485 	bus_space_handle_t  ioh;
1486 	u_int32_t data;
1487 	int timeout;
1488 
1489 	co  = aux;
1490 	sc  = co->sc;
1491 	iot = sc->sc_iot;
1492 	ioh = sc->sc_ioh;
1493 	if (auixp_wait_for_codecs(sc, "read_codec"))
1494 		return 0xffff;
1495 
1496 	/* build up command for reading codec register */
1497 	data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
1498 		ATI_REG_PHYS_OUT_ADDR_EN |
1499 		ATI_REG_PHYS_OUT_RW |
1500 		co->codec_nr;
1501 
1502 	bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, data);
1503 
1504 	if (auixp_wait_for_codecs(sc, "read_codec"))
1505 		return 0xffff;
1506 
1507 	/* wait until codec info is clocked in */
1508 	timeout = 500;		/* 500*2 usec -> 0.001 sec */
1509 	do {
1510 		data = bus_space_read_4(iot, ioh, ATI_REG_PHYS_IN_ADDR);
1511 		if (data & ATI_REG_PHYS_IN_READ_FLAG) {
1512 			DPRINTF(("read ac'97 codec reg 0x%x = 0x%08x\n",
1513 				reg, data >> ATI_REG_PHYS_IN_DATA_SHIFT));
1514 			*result = data >> ATI_REG_PHYS_IN_DATA_SHIFT;
1515 			return 0;
1516 		}
1517 		DELAY(2);
1518 		timeout--;
1519 	} while (timeout > 0);
1520 
1521 	if (reg < 0x7c)
1522 		printf("%s: codec read timeout! (reg %x)\n",
1523 		    sc->sc_dev.dv_xname, reg);
1524 
1525 	return 0xffff;
1526 }
1527 
1528 int
1529 auixp_write_codec(void *aux, u_int8_t reg, u_int16_t data)
1530 {
1531 	struct auixp_codec *co;
1532 	struct auixp_softc *sc;
1533 	bus_space_tag_t     iot;
1534 	bus_space_handle_t  ioh;
1535 	u_int32_t value;
1536 
1537 	DPRINTF(("write ac'97 codec reg 0x%x = 0x%08x\n", reg, data));
1538 	co  = aux;
1539 	sc  = co->sc;
1540 	iot = sc->sc_iot;
1541 	ioh = sc->sc_ioh;
1542 	if (auixp_wait_for_codecs(sc, "write_codec"))
1543 		return -1;
1544 
1545 	/* build up command for writing codec register */
1546 	value = (((u_int32_t) data) << ATI_REG_PHYS_OUT_DATA_SHIFT) |
1547 		(((u_int32_t)  reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
1548 		ATI_REG_PHYS_OUT_ADDR_EN |
1549 		co->codec_nr;
1550 
1551 	bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, value);
1552 
1553 	return 0;
1554 }
1555 
1556 void
1557 auixp_reset_codec(void *aux)
1558 {
1559 
1560 	/* nothing to be done? */
1561 }
1562 
1563 enum ac97_host_flags
1564 auixp_flags_codec(void *aux)
1565 {
1566 	struct auixp_codec *ixp_codec;
1567 
1568 	ixp_codec = aux;
1569 	return ixp_codec->codec_flags;
1570 }
1571 
1572 int
1573 auixp_wait_for_codecs(struct auixp_softc *sc, const char *func)
1574 {
1575 	bus_space_tag_t      iot;
1576 	bus_space_handle_t   ioh;
1577 	u_int32_t value;
1578 	int timeout;
1579 
1580 	iot = sc->sc_iot;
1581 	ioh = sc->sc_ioh;
1582 	/* wait until all codec transfers are done */
1583 	timeout = 500;		/* 500*2 usec -> 0.001 sec */
1584 	do {
1585 		value = bus_space_read_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR);
1586 		if ((value & ATI_REG_PHYS_OUT_ADDR_EN) == 0)
1587 			return 0;
1588 
1589 		DELAY(2);
1590 		timeout--;
1591 	} while (timeout > 0);
1592 
1593 	printf("%s: %s: timed out\n", func, sc->sc_dev.dv_xname);
1594 	return -1;
1595 }
1596 
1597 void
1598 auixp_autodetect_codecs(struct auixp_softc *sc)
1599 {
1600 	bus_space_tag_t      iot;
1601 	bus_space_handle_t   ioh;
1602 	pcireg_t subdev;
1603 	struct auixp_codec  *codec;
1604 	int timeout;
1605 
1606 	iot = sc->sc_iot;
1607 	ioh = sc->sc_ioh;
1608 	subdev = pci_conf_read(sc->sc_pct, sc->sc_tag, PCI_SUBSYS_ID_REG);
1609 
1610 	/* ATI IXP can have upto 3 codecs; mark all codecs as not existing */
1611 	sc->sc_codec_not_ready_bits = 0;
1612 
1613 	/* enable all codecs to interrupt as well as the new frame interrupt */
1614 	bus_space_write_4(iot, ioh, ATI_REG_IER, CODEC_CHECK_BITS);
1615 
1616 	/* wait for the interrupts to happen */
1617 	timeout = 100;		/* 100.000 usec -> 0.1 sec */
1618 
1619 	while (timeout > 0) {
1620 		DELAY(1000);
1621 		if (sc->sc_codec_not_ready_bits)
1622 			break;
1623 		timeout--;
1624 	}
1625 
1626 	if (timeout == 0)
1627 		printf("%s: WARNING: timeout during codec detection; "
1628 			"codecs might be present but haven't interrupted\n",
1629 			sc->sc_dev.dv_xname);
1630 
1631 	/* disable all interrupts for now */
1632 	auixp_disable_interrupts(sc);
1633 
1634 	/* Attach AC97 host interfaces */
1635 	codec = &sc->sc_codec;
1636 	bzero(codec, sizeof(struct auixp_codec));
1637 
1638 	codec->sc       = sc;
1639 
1640 	codec->host_if.arg    = codec;
1641 	codec->host_if.attach = auixp_attach_codec;
1642 	codec->host_if.read   = auixp_read_codec;
1643 	codec->host_if.write  = auixp_write_codec;
1644 	codec->host_if.reset  = auixp_reset_codec;
1645 	codec->host_if.flags  = auixp_flags_codec;
1646 	switch (subdev) {
1647 	case 0x1311462: /* MSI S270 */
1648 	case 0x1611462: /* LG K1 Express */
1649 	case 0x3511462: /* MSI L725 */
1650 	case 0x4711462: /* MSI L720 */
1651 	case 0x0611462: /* MSI S250 */
1652 		codec->codec_flags = AC97_HOST_ALC650_PIN47_IS_EAPD;
1653 		break;
1654 	}
1655 
1656 	if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC0_NOT_READY)) {
1657 		/* codec 0 present */
1658 		DPRINTF(("auixp : YAY! codec 0 present!\n"));
1659 		if (ac97_attach(&sc->sc_codec.host_if) == 0) {
1660 			sc->sc_codec.codec_nr = 0;
1661 			sc->sc_codec.present = 1;
1662 			return;
1663 		}
1664 	}
1665 
1666 	if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC1_NOT_READY)) {
1667 		/* codec 1 present */
1668 		DPRINTF(("auixp : YAY! codec 1 present!\n"));
1669 		if (ac97_attach(&sc->sc_codec.host_if) == 0) {
1670 			sc->sc_codec.codec_nr = 1;
1671 			sc->sc_codec.present = 1;
1672 			return;
1673 		}
1674 	}
1675 
1676 	if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC2_NOT_READY)) {
1677 		/* codec 2 present */
1678 		DPRINTF(("auixp : YAY! codec 2 present!\n"));
1679 		if (ac97_attach(&sc->sc_codec.host_if) == 0) {
1680 			sc->sc_codec.codec_nr = 2;
1681 			sc->sc_codec.present = 1;
1682 			return;
1683 		}
1684 	}
1685 }
1686 
1687 void
1688 auixp_disable_dma(struct auixp_softc *sc, struct auixp_dma *dma)
1689 {
1690 	bus_space_tag_t      iot;
1691 	bus_space_handle_t   ioh;
1692 	u_int32_t value;
1693 
1694 	iot = sc->sc_iot;
1695 	ioh = sc->sc_ioh;
1696 	/* lets not stress the DMA engine more than necessary */
1697 	value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1698 	if (value & dma->dma_enable_bit) {
1699 		value &= ~dma->dma_enable_bit;
1700 		bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1701 	}
1702 }
1703 
1704 void
1705 auixp_enable_dma(struct auixp_softc *sc, struct auixp_dma *dma)
1706 {
1707 	bus_space_tag_t      iot;
1708 	bus_space_handle_t   ioh;
1709 	u_int32_t value;
1710 
1711 	iot = sc->sc_iot;
1712 	ioh = sc->sc_ioh;
1713 	/* lets not stress the DMA engine more than necesssary */
1714 	value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1715 	if (!(value & dma->dma_enable_bit)) {
1716 		value |= dma->dma_enable_bit;
1717 		bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1718 	}
1719 }
1720 
1721 void
1722 auixp_reset_aclink(struct auixp_softc *sc)
1723 {
1724 	bus_space_tag_t      iot;
1725 	bus_space_handle_t   ioh;
1726 	u_int32_t value, timeout;
1727 
1728 	iot = sc->sc_iot;
1729 	ioh = sc->sc_ioh;
1730 
1731 	/* if power is down, power it up */
1732 	value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1733 	if (value & ATI_REG_CMD_POWERDOWN) {
1734 		printf("%s: powering up\n", sc->sc_dev.dv_xname);
1735 
1736 		/* explicitly enable power */
1737 		value &= ~ATI_REG_CMD_POWERDOWN;
1738 		bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1739 
1740 		/* have to wait at least 10 usec for it to initialise */
1741 		DELAY(20);
1742 	};
1743 
1744 	printf("%s: soft resetting aclink\n", sc->sc_dev.dv_xname);
1745 
1746 	/* perform a soft reset */
1747 	value  = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1748 	value |= ATI_REG_CMD_AC_SOFT_RESET;
1749 	bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1750 
1751 	/* need to read the CMD reg and wait aprox. 10 usec to init */
1752 	value  = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1753 	DELAY(20);
1754 
1755 	/* clear soft reset flag again */
1756 	value  = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1757 	value &= ~ATI_REG_CMD_AC_SOFT_RESET;
1758 	bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1759 
1760 	/* check if the ac-link is working; reset device otherwise */
1761 	timeout = 10;
1762 	value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1763 	while (!(value & ATI_REG_CMD_ACLINK_ACTIVE)) {
1764 		printf("%s: not up; resetting aclink hardware\n",
1765 				sc->sc_dev.dv_xname);
1766 
1767 		/* dip aclink reset but keep the acsync */
1768 		value &= ~ATI_REG_CMD_AC_RESET;
1769 		value |=  ATI_REG_CMD_AC_SYNC;
1770 		bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1771 
1772 		/* need to read CMD again and wait again (clocking in issue?) */
1773 		value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1774 		DELAY(20);
1775 
1776 		/* assert aclink reset again */
1777 		value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1778 		value |=  ATI_REG_CMD_AC_RESET;
1779 		bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1780 
1781 		/* check if its active now */
1782 		value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1783 
1784 		timeout--;
1785 		if (timeout == 0) break;
1786 	};
1787 
1788 	if (timeout == 0) {
1789 		printf("%s: giving up aclink reset\n", sc->sc_dev.dv_xname);
1790 	};
1791 	if (timeout != 10) {
1792 		printf("%s: aclink hardware reset successful\n",
1793 			sc->sc_dev.dv_xname);
1794 	};
1795 
1796 	/* assert reset and sync for safety */
1797 	value  = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1798 	value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET;
1799 	bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1800 }
1801 
1802 /* chip hard init */
1803 int
1804 auixp_init(struct auixp_softc *sc)
1805 {
1806 	bus_space_tag_t      iot;
1807 	bus_space_handle_t   ioh;
1808 	u_int32_t value;
1809 
1810 	iot = sc->sc_iot;
1811 	ioh = sc->sc_ioh;
1812 	/* disable all interrupts and clear all sources */
1813 	auixp_disable_interrupts(sc);
1814 
1815 	/* clear all DMA enables (preserving rest of settings) */
1816 	value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
1817 	value &= ~( ATI_REG_CMD_IN_DMA_EN  |
1818 		    ATI_REG_CMD_OUT_DMA_EN |
1819 		    ATI_REG_CMD_SPDF_OUT_EN );
1820 	bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
1821 
1822 	/* Reset AC-link */
1823 	auixp_reset_aclink(sc);
1824 
1825 	/*
1826 	 * codecs get auto-detected later
1827 	 *
1828 	 * note: we are NOT enabling interrupts yet, no codecs have been
1829 	 * detected yet nor is anything else set up
1830 	 */
1831 
1832 	return 0;
1833 }
1834