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