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