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