xref: /dragonfly/sys/dev/sound/pci/maestro.c (revision cfd1aba3)
1 /*-
2  * Copyright (c) 2000-2004 Taku YAMAMOTO <taku@tackymt.homeip.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *	maestro.c,v 1.23.2.1 2003/10/03 18:21:38 taku Exp
27  * $FreeBSD: src/sys/dev/sound/pci/maestro.c,v 1.28.2.3 2006/02/04 11:58:28 netchild Exp $
28  */
29 
30 /*
31  * Credits:
32  *
33  * Part of this code (especially in many magic numbers) was heavily inspired
34  * by the Linux driver originally written by
35  * Alan Cox <alan.cox@linux.org>, modified heavily by
36  * Zach Brown <zab@zabbo.net>.
37  *
38  * busdma()-ize and buffer size reduction were suggested by
39  * Cameron Grant <cg@freebsd.org>.
40  * Also he showed me the way to use busdma() suite.
41  *
42  * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500
43  * were looked at by
44  * Munehiro Matsuda <haro@tk.kubota.co.jp>,
45  * who brought patches based on the Linux driver with some simplification.
46  *
47  * Hardware volume controller was implemented by
48  * John Baldwin <jhb@freebsd.org>.
49  */
50 
51 #include <dev/sound/pcm/sound.h>
52 #include <dev/sound/pcm/ac97.h>
53 #include <bus/pci/pcireg.h>
54 #include <bus/pci/pcivar.h>
55 
56 #include <dev/sound/pci/maestro_reg.h>
57 
58 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/maestro.c,v 1.10 2007/06/16 20:07:19 dillon Exp $");
59 
60 
61 #define inline __inline
62 
63 /*
64  * PCI IDs of supported chips:
65  *
66  * MAESTRO-1	0x01001285
67  * MAESTRO-2	0x1968125d
68  * MAESTRO-2E	0x1978125d
69  */
70 
71 #define MAESTRO_1_PCI_ID	0x01001285
72 #define MAESTRO_2_PCI_ID	0x1968125d
73 #define MAESTRO_2E_PCI_ID	0x1978125d
74 
75 #define NEC_SUBID1	0x80581033	/* Taken from Linux driver */
76 #define NEC_SUBID2	0x803c1033	/* NEC VersaProNX VA26D    */
77 
78 #ifdef AGG_MAXPLAYCH
79 # if AGG_MAXPLAYCH > 4
80 #  undef AGG_MAXPLAYCH
81 #  define AGG_MAXPLAYCH 4
82 # endif
83 #else
84 # define AGG_MAXPLAYCH	4
85 #endif
86 
87 #define AGG_DEFAULT_BUFSZ	0x4000 /* 0x1000, but gets underflows */
88 
89 
90 /* compatibility */
91 # define critical_enter()	crit_enter()
92 # define critical_exit()	crit_exit()
93 
94 #ifndef PCIR_BAR
95 #define PCIR_BAR(x)	(PCIR_MAPS + (x) * 4)
96 #endif
97 
98 
99 /* -----------------------------
100  * Data structures.
101  */
102 struct agg_chinfo {
103 	/* parent softc */
104 	struct agg_info		*parent;
105 
106 	/* FreeBSD newpcm related */
107 	struct pcm_channel	*channel;
108 	struct snd_dbuf		*buffer;
109 
110 	/* OS independent */
111 	bus_addr_t		phys;	/* channel buffer physical address */
112 	bus_addr_t		base;	/* channel buffer segment base */
113 	u_int32_t		blklen;	/* DMA block length in WORDs */
114 	u_int32_t		buflen;	/* channel buffer length in WORDs */
115 	u_int32_t		speed;
116 	unsigned		num	: 3;
117 	unsigned		stereo	: 1;
118 	unsigned		qs16	: 1;	/* quantum size is 16bit */
119 	unsigned		us	: 1;	/* in unsigned format */
120 };
121 
122 struct agg_rchinfo {
123 	/* parent softc */
124 	struct agg_info		*parent;
125 
126 	/* FreeBSD newpcm related */
127 	struct pcm_channel	*channel;
128 	struct snd_dbuf		*buffer;
129 
130 	/* OS independent */
131 	bus_addr_t		phys;	/* channel buffer physical address */
132 	bus_addr_t		base;	/* channel buffer segment base */
133 	u_int32_t		blklen;	/* DMA block length in WORDs */
134 	u_int32_t		buflen;	/* channel buffer length in WORDs */
135 	u_int32_t		speed;
136 	unsigned			: 3;
137 	unsigned		stereo	: 1;
138 	bus_addr_t		srcphys;
139 	int16_t			*src;	/* stereo peer buffer */
140 	int16_t			*sink;	/* channel buffer pointer */
141 	volatile u_int32_t	hwptr;	/* ready point in 16bit sample */
142 };
143 
144 struct agg_info {
145 	/* FreeBSD newbus related */
146 	device_t		dev;
147 
148 	/* I wonder whether bus_space_* are in common in *BSD... */
149 	struct resource		*reg;
150 	int			regid;
151 	bus_space_tag_t		st;
152 	bus_space_handle_t	sh;
153 
154 	struct resource		*irq;
155 	int			irqid;
156 	void			*ih;
157 
158 	bus_dma_tag_t		buf_dmat;
159 	bus_dma_tag_t		stat_dmat;
160 
161 	/* FreeBSD SMPng related */
162 #ifdef USING_MUTEX
163 	sndlock_t		lock;
164 #endif
165 	/* FreeBSD newpcm related */
166 	struct ac97_info	*codec;
167 
168 	/* OS independent */
169 	u_int8_t		*stat;	/* status buffer pointer */
170 	bus_addr_t		phys;	/* status buffer physical address */
171 	unsigned int		bufsz;	/* channel buffer size in bytes */
172 	u_int			playchns;
173 	volatile u_int		active;
174 	struct agg_chinfo	pch[AGG_MAXPLAYCH];
175 	struct agg_rchinfo	rch;
176 	volatile u_int8_t	curpwr;	/* current power status: D[0-3] */
177 };
178 
179 
180 /* -----------------------------
181  * Sysctls for debug.
182  */
183 static unsigned int powerstate_active = PCI_POWERSTATE_D1;
184 #ifdef MAESTRO_AGGRESSIVE_POWERSAVE
185 static unsigned int powerstate_idle   = PCI_POWERSTATE_D2;
186 #else
187 static unsigned int powerstate_idle   = PCI_POWERSTATE_D1;
188 #endif
189 static unsigned int powerstate_init   = PCI_POWERSTATE_D2;
190 
191 SYSCTL_NODE(_debug, OID_AUTO, maestro, CTLFLAG_RD, 0, "");
192 SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_active, CTLFLAG_RW,
193 	    &powerstate_active, 0, "The Dx power state when active (0-1)");
194 SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_idle, CTLFLAG_RW,
195 	    &powerstate_idle, 0, "The Dx power state when idle (0-2)");
196 SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_init, CTLFLAG_RW,
197 	    &powerstate_init, 0, "The Dx power state prior to the first use (0-2)");
198 
199 
200 /* -----------------------------
201  * Prototypes
202  */
203 
204 static inline void	 agg_lock(struct agg_info*);
205 static inline void	 agg_unlock(struct agg_info*);
206 static inline void	 agg_sleep(struct agg_info*, const char *wmesg, int msec);
207 
208 static inline u_int32_t	 agg_rd(struct agg_info*, int, int size);
209 static inline void	 agg_wr(struct agg_info*, int, u_int32_t data, int size);
210 
211 static inline int	 agg_rdcodec(struct agg_info*, int);
212 static inline int	 agg_wrcodec(struct agg_info*, int, u_int32_t);
213 
214 static inline void	 ringbus_setdest(struct agg_info*, int, int);
215 
216 static inline u_int16_t	 wp_rdreg(struct agg_info*, u_int16_t);
217 static inline void	 wp_wrreg(struct agg_info*, u_int16_t, u_int16_t);
218 static inline u_int16_t	 wp_rdapu(struct agg_info*, unsigned, u_int16_t);
219 static inline void	 wp_wrapu(struct agg_info*, unsigned, u_int16_t, u_int16_t);
220 static inline void	 wp_settimer(struct agg_info*, u_int);
221 static inline void	 wp_starttimer(struct agg_info*);
222 static inline void	 wp_stoptimer(struct agg_info*);
223 
224 static inline u_int16_t	 wc_rdreg(struct agg_info*, u_int16_t);
225 static inline void	 wc_wrreg(struct agg_info*, u_int16_t, u_int16_t);
226 static inline u_int16_t	 wc_rdchctl(struct agg_info*, int);
227 static inline void	 wc_wrchctl(struct agg_info*, int, u_int16_t);
228 
229 static inline void	 agg_stopclock(struct agg_info*, int part, int st);
230 
231 static inline void	 agg_initcodec(struct agg_info*);
232 static void		 agg_init(struct agg_info*);
233 static void		 agg_power(struct agg_info*, int);
234 
235 static void		 aggch_start_dac(struct agg_chinfo*);
236 static void		 aggch_stop_dac(struct agg_chinfo*);
237 static void		 aggch_start_adc(struct agg_rchinfo*);
238 static void		 aggch_stop_adc(struct agg_rchinfo*);
239 static void		 aggch_feed_adc_stereo(struct agg_rchinfo*);
240 static void		 aggch_feed_adc_mono(struct agg_rchinfo*);
241 
242 static inline void	 suppress_jitter(struct agg_chinfo*);
243 static inline void	 suppress_rec_jitter(struct agg_rchinfo*);
244 
245 static void		 set_timer(struct agg_info*);
246 
247 static void		 agg_intr(void *);
248 static int		 agg_probe(device_t);
249 static int		 agg_attach(device_t);
250 static int		 agg_detach(device_t);
251 static int		 agg_suspend(device_t);
252 static int		 agg_resume(device_t);
253 static int		 agg_shutdown(device_t);
254 
255 static void	*dma_malloc(bus_dma_tag_t, u_int32_t, bus_addr_t*);
256 static void	 dma_free(bus_dma_tag_t, void *);
257 
258 
259 /* -----------------------------
260  * Subsystems.
261  */
262 
263 /* locking */
264 
265 static inline void
266 agg_lock(struct agg_info *sc)
267 {
268 #ifdef USING_MUTEX
269 	snd_mtxlock(sc->lock);
270 #endif
271 }
272 
273 static inline void
274 agg_unlock(struct agg_info *sc)
275 {
276 #ifdef USING_MUTEX
277 	snd_mtxunlock(sc->lock);
278 #endif
279 }
280 
281 static inline void
282 agg_sleep(struct agg_info *sc, const char *wmesg, int msec)
283 {
284 	int timo;
285 
286 	timo = msec * hz / 1000;
287 	if (timo == 0)
288 		timo = 1;
289 #ifdef USING_MUTEX
290 	snd_mtxsleep(sc, sc->lock, 0, wmesg, timo);
291 #else
292 	tsleep(sc, PWAIT, wmesg, timo);
293 #endif
294 }
295 
296 
297 /* I/O port */
298 
299 static inline u_int32_t
300 agg_rd(struct agg_info *sc, int regno, int size)
301 {
302 	switch (size) {
303 	case 1:
304 		return bus_space_read_1(sc->st, sc->sh, regno);
305 	case 2:
306 		return bus_space_read_2(sc->st, sc->sh, regno);
307 	case 4:
308 		return bus_space_read_4(sc->st, sc->sh, regno);
309 	default:
310 		return ~(u_int32_t)0;
311 	}
312 }
313 
314 #define AGG_RD(sc, regno, size)           \
315 	bus_space_read_##size(            \
316 	    ((struct agg_info*)(sc))->st, \
317 	    ((struct agg_info*)(sc))->sh, (regno))
318 
319 static inline void
320 agg_wr(struct agg_info *sc, int regno, u_int32_t data, int size)
321 {
322 	switch (size) {
323 	case 1:
324 		bus_space_write_1(sc->st, sc->sh, regno, data);
325 		break;
326 	case 2:
327 		bus_space_write_2(sc->st, sc->sh, regno, data);
328 		break;
329 	case 4:
330 		bus_space_write_4(sc->st, sc->sh, regno, data);
331 		break;
332 	}
333 }
334 
335 #define AGG_WR(sc, regno, data, size)     \
336 	bus_space_write_##size(           \
337 	    ((struct agg_info*)(sc))->st, \
338 	    ((struct agg_info*)(sc))->sh, (regno), (data))
339 
340 /* -------------------------------------------------------------------- */
341 
342 /* Codec/Ringbus */
343 
344 static inline int
345 agg_codec_wait4idle(struct agg_info *ess)
346 {
347 	unsigned t = 26;
348 
349 	while (AGG_RD(ess, PORT_CODEC_STAT, 1) & CODEC_STAT_MASK) {
350 		if (--t == 0)
351 			return EBUSY;
352 		DELAY(2);	/* 20.8us / 13 */
353 	}
354 	return 0;
355 }
356 
357 
358 static inline int
359 agg_rdcodec(struct agg_info *ess, int regno)
360 {
361 	int ret;
362 
363 	/* We have to wait for a SAFE time to write addr/data */
364 	if (agg_codec_wait4idle(ess)) {
365 		/* Timed out. No read performed. */
366 		device_printf(ess->dev, "agg_rdcodec() PROGLESS timed out.\n");
367 		return -1;
368 	}
369 
370 	AGG_WR(ess, PORT_CODEC_CMD, CODEC_CMD_READ | regno, 1);
371 	/*DELAY(21);	* AC97 cycle = 20.8usec */
372 
373 	/* Wait for data retrieve */
374 	if (!agg_codec_wait4idle(ess)) {
375 		ret = AGG_RD(ess, PORT_CODEC_REG, 2);
376 	} else {
377 		/* Timed out. No read performed. */
378 		device_printf(ess->dev, "agg_rdcodec() RW_DONE timed out.\n");
379 		ret = -1;
380 	}
381 
382 	return ret;
383 }
384 
385 static inline int
386 agg_wrcodec(struct agg_info *ess, int regno, u_int32_t data)
387 {
388 	/* We have to wait for a SAFE time to write addr/data */
389 	if (agg_codec_wait4idle(ess)) {
390 		/* Timed out. Abort writing. */
391 		device_printf(ess->dev, "agg_wrcodec() PROGLESS timed out.\n");
392 		return -1;
393 	}
394 
395 	AGG_WR(ess, PORT_CODEC_REG, data, 2);
396 	AGG_WR(ess, PORT_CODEC_CMD, CODEC_CMD_WRITE | regno, 1);
397 
398 	/* Wait for write completion */
399 	if (agg_codec_wait4idle(ess)) {
400 		/* Timed out. */
401 		device_printf(ess->dev, "agg_wrcodec() RW_DONE timed out.\n");
402 		return -1;
403 	}
404 
405 	return 0;
406 }
407 
408 static inline void
409 ringbus_setdest(struct agg_info *ess, int src, int dest)
410 {
411 	u_int32_t	data;
412 
413 	data = AGG_RD(ess, PORT_RINGBUS_CTRL, 4);
414 	data &= ~(0xfU << src);
415 	data |= (0xfU & dest) << src;
416 	AGG_WR(ess, PORT_RINGBUS_CTRL, data, 4);
417 }
418 
419 /* -------------------------------------------------------------------- */
420 
421 /* Wave Processor */
422 
423 static inline u_int16_t
424 wp_rdreg(struct agg_info *ess, u_int16_t reg)
425 {
426 	AGG_WR(ess, PORT_DSP_INDEX, reg, 2);
427 	return AGG_RD(ess, PORT_DSP_DATA, 2);
428 }
429 
430 static inline void
431 wp_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data)
432 {
433 	AGG_WR(ess, PORT_DSP_INDEX, reg, 2);
434 	AGG_WR(ess, PORT_DSP_DATA, data, 2);
435 }
436 
437 static inline int
438 wp_wait_data(struct agg_info *ess, u_int16_t data)
439 {
440 	unsigned t = 0;
441 
442 	while (AGG_RD(ess, PORT_DSP_DATA, 2) != data) {
443 		if (++t == 1000) {
444 			return EAGAIN;
445 		}
446 		AGG_WR(ess, PORT_DSP_DATA, data, 2);
447 	}
448 
449 	return 0;
450 }
451 
452 static inline u_int16_t
453 wp_rdapu(struct agg_info *ess, unsigned ch, u_int16_t reg)
454 {
455 	wp_wrreg(ess, WPREG_CRAM_PTR, reg | (ch << 4));
456 	if (wp_wait_data(ess, reg | (ch << 4)) != 0)
457 		device_printf(ess->dev, "wp_rdapu() indexing timed out.\n");
458 	return wp_rdreg(ess, WPREG_DATA_PORT);
459 }
460 
461 static inline void
462 wp_wrapu(struct agg_info *ess, unsigned ch, u_int16_t reg, u_int16_t data)
463 {
464 	wp_wrreg(ess, WPREG_CRAM_PTR, reg | (ch << 4));
465 	if (wp_wait_data(ess, reg | (ch << 4)) == 0) {
466 		wp_wrreg(ess, WPREG_DATA_PORT, data);
467 		if (wp_wait_data(ess, data) != 0)
468 			device_printf(ess->dev, "wp_wrapu() write timed out.\n");
469 	} else {
470 		device_printf(ess->dev, "wp_wrapu() indexing timed out.\n");
471 	}
472 }
473 
474 static void
475 apu_setparam(struct agg_info *ess, int apuch,
476     u_int32_t wpwa, u_int16_t size, int16_t pan, u_int dv)
477 {
478 	wp_wrapu(ess, apuch, APUREG_WAVESPACE, (wpwa >> 8) & APU_64KPAGE_MASK);
479 	wp_wrapu(ess, apuch, APUREG_CURPTR, wpwa);
480 	wp_wrapu(ess, apuch, APUREG_ENDPTR, wpwa + size);
481 	wp_wrapu(ess, apuch, APUREG_LOOPLEN, size);
482 	wp_wrapu(ess, apuch, APUREG_ROUTING, 0);
483 	wp_wrapu(ess, apuch, APUREG_AMPLITUDE, 0xf000);
484 	wp_wrapu(ess, apuch, APUREG_POSITION, 0x8f00
485 	    | (APU_RADIUS_MASK & (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT))
486 	    | (APU_PAN_MASK & ((pan + PAN_FRONT) << APU_PAN_SHIFT)));
487 	wp_wrapu(ess, apuch, APUREG_FREQ_LOBYTE,
488 	    APU_plus6dB | ((dv & 0xff) << APU_FREQ_LOBYTE_SHIFT));
489 	wp_wrapu(ess, apuch, APUREG_FREQ_HIWORD, dv >> 8);
490 }
491 
492 static inline void
493 wp_settimer(struct agg_info *ess, u_int divide)
494 {
495 	u_int prescale = 0;
496 
497 	RANGE(divide, 2, 32 << 7);
498 
499 	for (; divide > 32; divide >>= 1) {
500 		prescale++;
501 		divide++;
502 	}
503 
504 	for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1)
505 		prescale++;
506 
507 	wp_wrreg(ess, WPREG_TIMER_ENABLE, 0);
508 	wp_wrreg(ess, WPREG_TIMER_FREQ, 0x9000 |
509 	    (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1));
510 	wp_wrreg(ess, WPREG_TIMER_ENABLE, 1);
511 }
512 
513 static inline void
514 wp_starttimer(struct agg_info *ess)
515 {
516 	AGG_WR(ess, PORT_INT_STAT, 1, 2);
517 	AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_DSOUND_INT_ENABLED
518 	       | AGG_RD(ess, PORT_HOSTINT_CTRL, 2), 2);
519 	wp_wrreg(ess, WPREG_TIMER_START, 1);
520 }
521 
522 static inline void
523 wp_stoptimer(struct agg_info *ess)
524 {
525 	AGG_WR(ess, PORT_HOSTINT_CTRL, ~HOSTINT_CTRL_DSOUND_INT_ENABLED
526 	       & AGG_RD(ess, PORT_HOSTINT_CTRL, 2), 2);
527 	AGG_WR(ess, PORT_INT_STAT, 1, 2);
528 	wp_wrreg(ess, WPREG_TIMER_START, 0);
529 }
530 
531 /* -------------------------------------------------------------------- */
532 
533 /* WaveCache */
534 
535 static inline u_int16_t
536 wc_rdreg(struct agg_info *ess, u_int16_t reg)
537 {
538 	AGG_WR(ess, PORT_WAVCACHE_INDEX, reg, 2);
539 	return AGG_RD(ess, PORT_WAVCACHE_DATA, 2);
540 }
541 
542 static inline void
543 wc_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data)
544 {
545 	AGG_WR(ess, PORT_WAVCACHE_INDEX, reg, 2);
546 	AGG_WR(ess, PORT_WAVCACHE_DATA, data, 2);
547 }
548 
549 static inline u_int16_t
550 wc_rdchctl(struct agg_info *ess, int ch)
551 {
552 	return wc_rdreg(ess, ch << 3);
553 }
554 
555 static inline void
556 wc_wrchctl(struct agg_info *ess, int ch, u_int16_t data)
557 {
558 	wc_wrreg(ess, ch << 3, data);
559 }
560 
561 /* -------------------------------------------------------------------- */
562 
563 /* Power management */
564 static inline void
565 agg_stopclock(struct agg_info *ess, int part, int st)
566 {
567 	u_int32_t data;
568 
569 	data = pci_read_config(ess->dev, CONF_ACPI_STOPCLOCK, 4);
570 	if (part < 16) {
571 		if (st == PCI_POWERSTATE_D1)
572 			data &= ~(1 << part);
573 		else
574 			data |= (1 << part);
575 		if (st == PCI_POWERSTATE_D1 || st == PCI_POWERSTATE_D2)
576 			data |= (0x10000 << part);
577 		else
578 			data &= ~(0x10000 << part);
579 		pci_write_config(ess->dev, CONF_ACPI_STOPCLOCK, data, 4);
580 	}
581 }
582 
583 
584 /* -----------------------------
585  * Controller.
586  */
587 
588 static inline void
589 agg_initcodec(struct agg_info* ess)
590 {
591 	u_int16_t data;
592 
593 	if (AGG_RD(ess, PORT_RINGBUS_CTRL, 4) & RINGBUS_CTRL_ACLINK_ENABLED) {
594 		AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4);
595 		DELAY(104);	/* 20.8us * (4 + 1) */
596 	}
597 	/* XXX - 2nd codec should be looked at. */
598 	AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_AC97_SWRESET, 4);
599 	DELAY(2);
600 	AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED, 4);
601 	DELAY(50);
602 
603 	if (agg_rdcodec(ess, 0) < 0) {
604 		AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4);
605 		DELAY(21);
606 
607 		/* Try cold reset. */
608 		device_printf(ess->dev, "will perform cold reset.\n");
609 		data = AGG_RD(ess, PORT_GPIO_DIR, 2);
610 		if (pci_read_config(ess->dev, 0x58, 2) & 1)
611 			data |= 0x10;
612 		data |= 0x009 & ~AGG_RD(ess, PORT_GPIO_DATA, 2);
613 		AGG_WR(ess, PORT_GPIO_MASK, 0xff6, 2);
614 		AGG_WR(ess, PORT_GPIO_DIR, data | 0x009, 2);
615 		AGG_WR(ess, PORT_GPIO_DATA, 0x000, 2);
616 		DELAY(2);
617 		AGG_WR(ess, PORT_GPIO_DATA, 0x001, 2);
618 		DELAY(1);
619 		AGG_WR(ess, PORT_GPIO_DATA, 0x009, 2);
620 		agg_sleep(ess, "agginicd", 500);
621 		AGG_WR(ess, PORT_GPIO_DIR, data, 2);
622 		DELAY(84);	/* 20.8us * 4 */
623 		AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED, 4);
624 		DELAY(50);
625 	}
626 }
627 
628 static void
629 agg_init(struct agg_info* ess)
630 {
631 	u_int32_t data;
632 
633 	/* Setup PCI config registers. */
634 
635 	/* Disable all legacy emulations. */
636 	data = pci_read_config(ess->dev, CONF_LEGACY, 2);
637 	data |= LEGACY_DISABLED;
638 	pci_write_config(ess->dev, CONF_LEGACY, data, 2);
639 
640 	/* Disconnect from CHI. (Makes Dell inspiron 7500 work?)
641 	 * Enable posted write.
642 	 * Prefer PCI timing rather than that of ISA.
643 	 * Don't swap L/R. */
644 	data = pci_read_config(ess->dev, CONF_MAESTRO, 4);
645 	data |= MAESTRO_PMC;
646 	data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING;
647 	data &= ~MAESTRO_SWAP_LR;
648 	pci_write_config(ess->dev, CONF_MAESTRO, data, 4);
649 
650 	/* Turn off unused parts if necessary. */
651 	/* consult CONF_MAESTRO. */
652 	if (data & MAESTRO_SPDIF)
653 		agg_stopclock(ess, ACPI_PART_SPDIF,	PCI_POWERSTATE_D2);
654 	else
655 		agg_stopclock(ess, ACPI_PART_SPDIF,	PCI_POWERSTATE_D1);
656 	if (data & MAESTRO_HWVOL)
657 		agg_stopclock(ess, ACPI_PART_HW_VOL,	PCI_POWERSTATE_D3);
658 	else
659 		agg_stopclock(ess, ACPI_PART_HW_VOL,	PCI_POWERSTATE_D1);
660 
661 	/* parts that never be used */
662 	agg_stopclock(ess, ACPI_PART_978,	PCI_POWERSTATE_D1);
663 	agg_stopclock(ess, ACPI_PART_DAA,	PCI_POWERSTATE_D1);
664 	agg_stopclock(ess, ACPI_PART_GPIO,	PCI_POWERSTATE_D1);
665 	agg_stopclock(ess, ACPI_PART_SB,	PCI_POWERSTATE_D1);
666 	agg_stopclock(ess, ACPI_PART_FM,	PCI_POWERSTATE_D1);
667 	agg_stopclock(ess, ACPI_PART_MIDI,	PCI_POWERSTATE_D1);
668 	agg_stopclock(ess, ACPI_PART_GAME_PORT,	PCI_POWERSTATE_D1);
669 
670 	/* parts that will be used only when play/recording */
671 	agg_stopclock(ess, ACPI_PART_WP,	PCI_POWERSTATE_D2);
672 
673 	/* parts that should always be turned on */
674 	agg_stopclock(ess, ACPI_PART_CODEC_CLOCK, PCI_POWERSTATE_D3);
675 	agg_stopclock(ess, ACPI_PART_GLUE,	PCI_POWERSTATE_D3);
676 	agg_stopclock(ess, ACPI_PART_PCI_IF,	PCI_POWERSTATE_D3);
677 	agg_stopclock(ess, ACPI_PART_RINGBUS,	PCI_POWERSTATE_D3);
678 
679 	/* Reset direct sound. */
680 	AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_SOFT_RESET, 2);
681 	DELAY(100);
682 	AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
683 	DELAY(100);
684 	AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_DSOUND_RESET, 2);
685 	DELAY(100);
686 	AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
687 	DELAY(100);
688 
689 	/* Enable hardware volume control interruption. */
690 	if (data & MAESTRO_HWVOL)	/* XXX - why not use device flags? */
691 		AGG_WR(ess, PORT_HOSTINT_CTRL,HOSTINT_CTRL_HWVOL_ENABLED, 2);
692 
693 	/* Setup Wave Processor. */
694 
695 	/* Enable WaveCache, set DMA base address. */
696 	wp_wrreg(ess, WPREG_WAVE_ROMRAM,
697 	    WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED);
698 	wp_wrreg(ess, WPREG_CRAM_DATA, 0);
699 
700 	AGG_WR(ess, PORT_WAVCACHE_CTRL,
701 	       WAVCACHE_ENABLED | WAVCACHE_WTSIZE_2MB | WAVCACHE_SGC_32_47, 2);
702 
703 	for (data = WAVCACHE_PCMBAR; data < WAVCACHE_PCMBAR + 4; data++)
704 		wc_wrreg(ess, data, ess->phys >> WAVCACHE_BASEADDR_SHIFT);
705 
706 	/* Setup Codec/Ringbus. */
707 	agg_initcodec(ess);
708 	AGG_WR(ess, PORT_RINGBUS_CTRL,
709 	       RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED, 4);
710 
711 	wp_wrreg(ess, 0x08, 0xB004);
712 	wp_wrreg(ess, 0x09, 0x001B);
713 	wp_wrreg(ess, 0x0A, 0x8000);
714 	wp_wrreg(ess, 0x0B, 0x3F37);
715 	wp_wrreg(ess, WPREG_BASE, 0x8598);	/* Parallel I/O */
716 	wp_wrreg(ess, WPREG_BASE + 1, 0x7632);
717 	ringbus_setdest(ess, RINGBUS_SRC_ADC,
718 	    RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN);
719 	ringbus_setdest(ess, RINGBUS_SRC_DSOUND,
720 	    RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC);
721 
722 	/* Enable S/PDIF if necessary. */
723 	if (pci_read_config(ess->dev, CONF_MAESTRO, 4) & MAESTRO_SPDIF)
724 		/* XXX - why not use device flags? */
725 		AGG_WR(ess, PORT_RINGBUS_CTRL_B, RINGBUS_CTRL_SPDIF |
726 		       AGG_RD(ess, PORT_RINGBUS_CTRL_B, 1), 1);
727 
728 	/* Setup ASSP. Needed for Dell Inspiron 7500? */
729 	AGG_WR(ess, PORT_ASSP_CTRL_B, 0x00, 1);
730 	AGG_WR(ess, PORT_ASSP_CTRL_A, 0x03, 1);
731 	AGG_WR(ess, PORT_ASSP_CTRL_C, 0x00, 1);
732 
733 	/*
734 	 * Setup GPIO.
735 	 * There seems to be speciality with NEC systems.
736 	 */
737 	switch (pci_get_subvendor(ess->dev)
738 	    | (pci_get_subdevice(ess->dev) << 16)) {
739 	case NEC_SUBID1:
740 	case NEC_SUBID2:
741 		/* Matthew Braithwaite <matt@braithwaite.net> reported that
742 		 * NEC Versa LX doesn't need GPIO operation. */
743 		AGG_WR(ess, PORT_GPIO_MASK, 0x9ff, 2);
744 		AGG_WR(ess, PORT_GPIO_DIR,
745 		       AGG_RD(ess, PORT_GPIO_DIR, 2) | 0x600, 2);
746 		AGG_WR(ess, PORT_GPIO_DATA, 0x200, 2);
747 		break;
748 	}
749 }
750 
751 /* Deals power state transition. Must be called with softc->lock held. */
752 static void
753 agg_power(struct agg_info *ess, int status)
754 {
755 	u_int8_t lastpwr;
756 
757 	lastpwr = ess->curpwr;
758 	if (lastpwr == status)
759 		return;
760 
761 	switch (status) {
762 	case PCI_POWERSTATE_D0:
763 	case PCI_POWERSTATE_D1:
764 		switch (lastpwr) {
765 		case PCI_POWERSTATE_D2:
766 			pci_set_powerstate(ess->dev, status);
767 			/* Turn on PCM-related parts. */
768 			agg_wrcodec(ess, AC97_REG_POWER, 0);
769 			DELAY(100);
770 #if 0
771 			if ((agg_rdcodec(ess, AC97_REG_POWER) & 3) != 3)
772 				device_printf(ess->dev, "warning: codec not ready.\n");
773 #endif
774 			AGG_WR(ess, PORT_RINGBUS_CTRL,
775 			       (AGG_RD(ess, PORT_RINGBUS_CTRL, 4)
776 				& ~RINGBUS_CTRL_ACLINK_ENABLED)
777 			       | RINGBUS_CTRL_RINGBUS_ENABLED, 4);
778 			DELAY(50);
779 			AGG_WR(ess, PORT_RINGBUS_CTRL,
780 			       AGG_RD(ess, PORT_RINGBUS_CTRL, 4)
781 			       | RINGBUS_CTRL_ACLINK_ENABLED, 4);
782 			break;
783 		case PCI_POWERSTATE_D3:
784 			/* Initialize. */
785 			pci_set_powerstate(ess->dev, PCI_POWERSTATE_D0);
786 			DELAY(100);
787 			agg_init(ess);
788 			/* FALLTHROUGH */
789 		case PCI_POWERSTATE_D0:
790 		case PCI_POWERSTATE_D1:
791 			pci_set_powerstate(ess->dev, status);
792 			break;
793 		}
794 		break;
795 	case PCI_POWERSTATE_D2:
796 		switch (lastpwr) {
797 		case PCI_POWERSTATE_D3:
798 			/* Initialize. */
799 			pci_set_powerstate(ess->dev, PCI_POWERSTATE_D0);
800 			DELAY(100);
801 			agg_init(ess);
802 			/* FALLTHROUGH */
803 		case PCI_POWERSTATE_D0:
804 		case PCI_POWERSTATE_D1:
805 			/* Turn off PCM-related parts. */
806 			AGG_WR(ess, PORT_RINGBUS_CTRL,
807 			       AGG_RD(ess, PORT_RINGBUS_CTRL, 4)
808 			       & ~RINGBUS_CTRL_RINGBUS_ENABLED, 4);
809 			DELAY(100);
810 			agg_wrcodec(ess, AC97_REG_POWER, 0x300);
811 			DELAY(100);
812 			break;
813 		}
814 		pci_set_powerstate(ess->dev, status);
815 		break;
816 	case PCI_POWERSTATE_D3:
817 		/* Entirely power down. */
818 		agg_wrcodec(ess, AC97_REG_POWER, 0xdf00);
819 		DELAY(100);
820 		AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4);
821 		/*DELAY(1);*/
822 		if (lastpwr != PCI_POWERSTATE_D2)
823 			wp_stoptimer(ess);
824 		AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
825 		AGG_WR(ess, PORT_HOSTINT_STAT, 0xff, 1);
826 		pci_set_powerstate(ess->dev, status);
827 		break;
828 	default:
829 		/* Invalid power state; let it ignored. */
830 		status = lastpwr;
831 		break;
832 	}
833 
834 	ess->curpwr = status;
835 }
836 
837 /* -------------------------------------------------------------------- */
838 
839 /* Channel controller. */
840 
841 static void
842 aggch_start_dac(struct agg_chinfo *ch)
843 {
844 	bus_addr_t	wpwa;
845 	u_int32_t	speed;
846 	u_int16_t	size, apuch, wtbar, wcreg, aputype;
847 	u_int		dv;
848 	int		pan;
849 
850 	speed = ch->speed;
851 	wpwa = (ch->phys - ch->base) >> 1;
852 	wtbar = 0xc & (wpwa >> WPWA_WTBAR_SHIFT(2));
853 	wcreg = (ch->phys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
854 	size  = ch->buflen;
855 	apuch = (ch->num << 1) | 32;
856 	pan = PAN_RIGHT - PAN_FRONT;
857 
858 	if (ch->stereo) {
859 		wcreg |= WAVCACHE_CHCTL_STEREO;
860 		if (ch->qs16) {
861 			aputype = APUTYPE_16BITSTEREO;
862 			wpwa >>= 1;
863 			size >>= 1;
864 			pan = -pan;
865 		} else
866 			aputype = APUTYPE_8BITSTEREO;
867 	} else {
868 		pan = 0;
869 		if (ch->qs16)
870 			aputype = APUTYPE_16BITLINEAR;
871 		else {
872 			aputype = APUTYPE_8BITLINEAR;
873 			speed >>= 1;
874 		}
875 	}
876 	if (ch->us)
877 		wcreg |= WAVCACHE_CHCTL_U8;
878 
879 	if (wtbar > 8)
880 		wtbar = (wtbar >> 1) + 4;
881 
882 	dv = (((speed % 48000) << 16) + 24000) / 48000
883 	    + ((speed / 48000) << 16);
884 
885 	agg_lock(ch->parent);
886 	agg_power(ch->parent, powerstate_active);
887 
888 	wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar,
889 	    ch->base >> WAVCACHE_BASEADDR_SHIFT);
890 	wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 1,
891 	    ch->base >> WAVCACHE_BASEADDR_SHIFT);
892 	if (wtbar < 8) {
893 		wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 2,
894 		    ch->base >> WAVCACHE_BASEADDR_SHIFT);
895 		wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 3,
896 		    ch->base >> WAVCACHE_BASEADDR_SHIFT);
897 	}
898 	wc_wrchctl(ch->parent, apuch, wcreg);
899 	wc_wrchctl(ch->parent, apuch + 1, wcreg);
900 
901 	apu_setparam(ch->parent, apuch, wpwa, size, pan, dv);
902 	if (ch->stereo) {
903 		if (ch->qs16)
904 			wpwa |= (WPWA_STEREO >> 1);
905 		apu_setparam(ch->parent, apuch + 1, wpwa, size, -pan, dv);
906 
907 		critical_enter();
908 		wp_wrapu(ch->parent, apuch, APUREG_APUTYPE,
909 		    (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
910 		wp_wrapu(ch->parent, apuch + 1, APUREG_APUTYPE,
911 		    (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
912 		critical_exit();
913 	} else {
914 		wp_wrapu(ch->parent, apuch, APUREG_APUTYPE,
915 		    (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
916 	}
917 
918 	/* to mark that this channel is ready for intr. */
919 	ch->parent->active |= (1 << ch->num);
920 
921 	set_timer(ch->parent);
922 	wp_starttimer(ch->parent);
923 	agg_unlock(ch->parent);
924 }
925 
926 static void
927 aggch_stop_dac(struct agg_chinfo *ch)
928 {
929 	agg_lock(ch->parent);
930 
931 	/* to mark that this channel no longer needs further intrs. */
932 	ch->parent->active &= ~(1 << ch->num);
933 
934 	wp_wrapu(ch->parent, (ch->num << 1) | 32, APUREG_APUTYPE,
935 	    APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
936 	wp_wrapu(ch->parent, (ch->num << 1) | 33, APUREG_APUTYPE,
937 	    APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
938 
939 	if (ch->parent->active) {
940 		set_timer(ch->parent);
941 		wp_starttimer(ch->parent);
942 	} else {
943 		wp_stoptimer(ch->parent);
944 		agg_power(ch->parent, powerstate_idle);
945 	}
946 	agg_unlock(ch->parent);
947 }
948 
949 static void
950 aggch_start_adc(struct agg_rchinfo *ch)
951 {
952 	bus_addr_t	wpwa, wpwa2;
953 	u_int16_t	wcreg, wcreg2;
954 	u_int	dv;
955 	int	pan;
956 
957 	/* speed > 48000 not cared */
958 	dv = ((ch->speed << 16) + 24000) / 48000;
959 
960 	/* RATECONV doesn't seem to like dv == 0x10000. */
961 	if (dv == 0x10000)
962 		dv--;
963 
964 	if (ch->stereo) {
965 		wpwa = (ch->srcphys - ch->base) >> 1;
966 		wpwa2 = (ch->srcphys + ch->parent->bufsz/2 - ch->base) >> 1;
967 		wcreg = (ch->srcphys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
968 		wcreg2 = (ch->base - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
969 		pan = PAN_LEFT - PAN_FRONT;
970 	} else {
971 		wpwa = (ch->phys - ch->base) >> 1;
972 		wpwa2 = (ch->srcphys - ch->base) >> 1;
973 		wcreg = (ch->phys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
974 		wcreg2 = (ch->base - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
975 		pan = 0;
976 	}
977 
978 	agg_lock(ch->parent);
979 
980 	ch->hwptr = 0;
981 	agg_power(ch->parent, powerstate_active);
982 
983 	/* Invalidate WaveCache. */
984 	wc_wrchctl(ch->parent, 0, wcreg | WAVCACHE_CHCTL_STEREO);
985 	wc_wrchctl(ch->parent, 1, wcreg | WAVCACHE_CHCTL_STEREO);
986 	wc_wrchctl(ch->parent, 2, wcreg2 | WAVCACHE_CHCTL_STEREO);
987 	wc_wrchctl(ch->parent, 3, wcreg2 | WAVCACHE_CHCTL_STEREO);
988 
989 	/* Load APU registers. */
990 	/* APU #0 : Sample rate converter for left/center. */
991 	apu_setparam(ch->parent, 0, WPWA_USE_SYSMEM | wpwa,
992 		     ch->buflen >> ch->stereo, 0, dv);
993 	wp_wrapu(ch->parent, 0, APUREG_AMPLITUDE, 0);
994 	wp_wrapu(ch->parent, 0, APUREG_ROUTING, 2 << APU_DATASRC_A_SHIFT);
995 
996 	/* APU #1 : Sample rate converter for right. */
997 	apu_setparam(ch->parent, 1, WPWA_USE_SYSMEM | wpwa2,
998 		     ch->buflen >> ch->stereo, 0, dv);
999 	wp_wrapu(ch->parent, 1, APUREG_AMPLITUDE, 0);
1000 	wp_wrapu(ch->parent, 1, APUREG_ROUTING, 3 << APU_DATASRC_A_SHIFT);
1001 
1002 	/* APU #2 : Input mixer for left. */
1003 	apu_setparam(ch->parent, 2, WPWA_USE_SYSMEM | 0,
1004 		     ch->parent->bufsz >> 2, pan, 0x10000);
1005 	wp_wrapu(ch->parent, 2, APUREG_AMPLITUDE, 0);
1006 	wp_wrapu(ch->parent, 2, APUREG_EFFECT_GAIN, 0xf0);
1007 	wp_wrapu(ch->parent, 2, APUREG_ROUTING, 0x15 << APU_DATASRC_A_SHIFT);
1008 
1009 	/* APU #3 : Input mixer for right. */
1010 	apu_setparam(ch->parent, 3, WPWA_USE_SYSMEM | (ch->parent->bufsz >> 2),
1011 		     ch->parent->bufsz >> 2, -pan, 0x10000);
1012 	wp_wrapu(ch->parent, 3, APUREG_AMPLITUDE, 0);
1013 	wp_wrapu(ch->parent, 3, APUREG_EFFECT_GAIN, 0xf0);
1014 	wp_wrapu(ch->parent, 3, APUREG_ROUTING, 0x14 << APU_DATASRC_A_SHIFT);
1015 
1016 	/* to mark this channel ready for intr. */
1017 	ch->parent->active |= (1 << ch->parent->playchns);
1018 
1019 	/* start adc */
1020 	critical_enter();
1021 	wp_wrapu(ch->parent, 0, APUREG_APUTYPE,
1022 	    (APUTYPE_RATECONV << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1023 	wp_wrapu(ch->parent, 1, APUREG_APUTYPE,
1024 	    (APUTYPE_RATECONV << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1025 	wp_wrapu(ch->parent, 2, APUREG_APUTYPE,
1026 	    (APUTYPE_INPUTMIXER << APU_APUTYPE_SHIFT) | 0xf);
1027 	wp_wrapu(ch->parent, 3, APUREG_APUTYPE,
1028 	    (APUTYPE_INPUTMIXER << APU_APUTYPE_SHIFT) | 0xf);
1029 	critical_exit();
1030 
1031 	set_timer(ch->parent);
1032 	wp_starttimer(ch->parent);
1033 	agg_unlock(ch->parent);
1034 }
1035 
1036 static void
1037 aggch_stop_adc(struct agg_rchinfo *ch)
1038 {
1039 	int apuch;
1040 
1041 	agg_lock(ch->parent);
1042 
1043 	/* to mark that this channel no longer needs further intrs. */
1044 	ch->parent->active &= ~(1 << ch->parent->playchns);
1045 
1046 	for (apuch = 0; apuch < 4; apuch++)
1047 		wp_wrapu(ch->parent, apuch, APUREG_APUTYPE,
1048 		    APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1049 
1050 	if (ch->parent->active) {
1051 		set_timer(ch->parent);
1052 		wp_starttimer(ch->parent);
1053 	} else {
1054 		wp_stoptimer(ch->parent);
1055 		agg_power(ch->parent, powerstate_idle);
1056 	}
1057 	agg_unlock(ch->parent);
1058 }
1059 
1060 /*
1061  * Feed from L/R channel of ADC to destination with stereo interleaving.
1062  * This function expects n not overwrapping the buffer boundary.
1063  * Note that n is measured in sample unit.
1064  *
1065  * XXX - this function works in 16bit stereo format only.
1066  */
1067 static inline void
1068 interleave(int16_t *l, int16_t *r, int16_t *p, unsigned n)
1069 {
1070 	int16_t *end;
1071 
1072 	for (end = l + n; l < end; ) {
1073 		*p++ = *l++;
1074 		*p++ = *r++;
1075 	}
1076 }
1077 
1078 static void
1079 aggch_feed_adc_stereo(struct agg_rchinfo *ch)
1080 {
1081 	unsigned cur, last;
1082 	int16_t *src2;
1083 
1084 	agg_lock(ch->parent);
1085 	cur = wp_rdapu(ch->parent, 0, APUREG_CURPTR);
1086 	agg_unlock(ch->parent);
1087 	cur -= 0xffff & ((ch->srcphys - ch->base) >> 1);
1088 	last = ch->hwptr;
1089 	src2 = ch->src + ch->parent->bufsz/4;
1090 
1091 	if (cur < last) {
1092 		interleave(ch->src + last, src2 + last,
1093 			   ch->sink + 2*last, ch->buflen/2 - last);
1094 		interleave(ch->src, src2,
1095 			   ch->sink, cur);
1096 	} else if (cur > last)
1097 		interleave(ch->src + last, src2 + last,
1098 			   ch->sink + 2*last, cur - last);
1099 	ch->hwptr = cur;
1100 }
1101 
1102 /*
1103  * Feed from R channel of ADC and mixdown to destination L/center.
1104  * This function expects n not overwrapping the buffer boundary.
1105  * Note that n is measured in sample unit.
1106  *
1107  * XXX - this function works in 16bit monoral format only.
1108  */
1109 static inline void
1110 mixdown(int16_t *src, int16_t *dest, unsigned n)
1111 {
1112 	int16_t *end;
1113 
1114 	for (end = dest + n; dest < end; dest++)
1115 		*dest = (int16_t)(((int)*dest - (int)*src++) / 2);
1116 }
1117 
1118 static void
1119 aggch_feed_adc_mono(struct agg_rchinfo *ch)
1120 {
1121 	unsigned cur, last;
1122 
1123 	agg_lock(ch->parent);
1124 	cur = wp_rdapu(ch->parent, 0, APUREG_CURPTR);
1125 	agg_unlock(ch->parent);
1126 	cur -= 0xffff & ((ch->phys - ch->base) >> 1);
1127 	last = ch->hwptr;
1128 
1129 	if (cur < last) {
1130 		mixdown(ch->src + last, ch->sink + last, ch->buflen - last);
1131 		mixdown(ch->src, ch->sink, cur);
1132 	} else if (cur > last)
1133 		mixdown(ch->src + last, ch->sink + last, cur - last);
1134 	ch->hwptr = cur;
1135 }
1136 
1137 /*
1138  * Stereo jitter suppressor.
1139  * Sometimes playback pointers differ in stereo-paired channels.
1140  * Calling this routine within intr fixes the problem.
1141  */
1142 static inline void
1143 suppress_jitter(struct agg_chinfo *ch)
1144 {
1145 	if (ch->stereo) {
1146 		int cp1, cp2, diff /*, halfsize*/ ;
1147 
1148 		/*halfsize = (ch->qs16? ch->buflen >> 2 : ch->buflen >> 1);*/
1149 		cp1 = wp_rdapu(ch->parent, (ch->num << 1) | 32, APUREG_CURPTR);
1150 		cp2 = wp_rdapu(ch->parent, (ch->num << 1) | 33, APUREG_CURPTR);
1151 		if (cp1 != cp2) {
1152 			diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1);
1153 			if (diff > 1 /* && diff < halfsize*/ )
1154 				AGG_WR(ch->parent, PORT_DSP_DATA, cp1, 2);
1155 		}
1156 	}
1157 }
1158 
1159 static inline void
1160 suppress_rec_jitter(struct agg_rchinfo *ch)
1161 {
1162 	int cp1, cp2, diff /*, halfsize*/ ;
1163 
1164 	/*halfsize = (ch->stereo? ch->buflen >> 2 : ch->buflen >> 1);*/
1165 	cp1 = (ch->stereo? ch->parent->bufsz >> 2 : ch->parent->bufsz >> 1)
1166 		+ wp_rdapu(ch->parent, 0, APUREG_CURPTR);
1167 	cp2 = wp_rdapu(ch->parent, 1, APUREG_CURPTR);
1168 	if (cp1 != cp2) {
1169 		diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1);
1170 		if (diff > 1 /* && diff < halfsize*/ )
1171 			AGG_WR(ch->parent, PORT_DSP_DATA, cp1, 2);
1172 	}
1173 }
1174 
1175 static inline u_int
1176 calc_timer_div(struct agg_chinfo *ch)
1177 {
1178 	u_int speed;
1179 
1180 	speed = ch->speed;
1181 #ifdef INVARIANTS
1182 	if (speed == 0) {
1183 		kprintf("snd_maestro: pch[%d].speed == 0, which shouldn't\n",
1184 		       ch->num);
1185 		speed = 1;
1186 	}
1187 #endif
1188 	return (48000 * (ch->blklen << (!ch->qs16 + !ch->stereo))
1189 		+ speed - 1) / speed;
1190 }
1191 
1192 static inline u_int
1193 calc_timer_div_rch(struct agg_rchinfo *ch)
1194 {
1195 	u_int speed;
1196 
1197 	speed = ch->speed;
1198 #ifdef INVARIANTS
1199 	if (speed == 0) {
1200 		kprintf("snd_maestro: rch.speed == 0, which shouldn't\n");
1201 		speed = 1;
1202 	}
1203 #endif
1204 	return (48000 * (ch->blklen << (!ch->stereo))
1205 		+ speed - 1) / speed;
1206 }
1207 
1208 static void
1209 set_timer(struct agg_info *ess)
1210 {
1211 	int i;
1212 	u_int	dv = 32 << 7, newdv;
1213 
1214 	for (i = 0; i < ess->playchns; i++)
1215 		if ((ess->active & (1 << i)) &&
1216 		    (dv > (newdv = calc_timer_div(ess->pch + i))))
1217 			dv = newdv;
1218 	if ((ess->active & (1 << i)) &&
1219 	    (dv > (newdv = calc_timer_div_rch(&ess->rch))))
1220 		dv = newdv;
1221 
1222 	wp_settimer(ess, dv);
1223 }
1224 
1225 
1226 /* -----------------------------
1227  * Newpcm glue.
1228  */
1229 
1230 /* AC97 mixer interface. */
1231 
1232 static u_int32_t
1233 agg_ac97_init(kobj_t obj, void *sc)
1234 {
1235 	struct agg_info *ess = sc;
1236 
1237 	return (AGG_RD(ess, PORT_CODEC_STAT, 1) & CODEC_STAT_MASK)? 0 : 1;
1238 }
1239 
1240 static int
1241 agg_ac97_read(kobj_t obj, void *sc, int regno)
1242 {
1243 	struct agg_info *ess = sc;
1244 	int ret;
1245 
1246 	/* XXX sound locking violation: agg_lock(ess); */
1247 	ret = agg_rdcodec(ess, regno);
1248 	/* agg_unlock(ess); */
1249 	return ret;
1250 }
1251 
1252 static int
1253 agg_ac97_write(kobj_t obj, void *sc, int regno, u_int32_t data)
1254 {
1255 	struct agg_info *ess = sc;
1256 	int ret;
1257 
1258 	/* XXX sound locking violation: agg_lock(ess); */
1259 	ret = agg_wrcodec(ess, regno, data);
1260 	/* agg_unlock(ess); */
1261 	return ret;
1262 }
1263 
1264 
1265 static kobj_method_t agg_ac97_methods[] = {
1266     	KOBJMETHOD(ac97_init,		agg_ac97_init),
1267     	KOBJMETHOD(ac97_read,		agg_ac97_read),
1268     	KOBJMETHOD(ac97_write,		agg_ac97_write),
1269 	KOBJMETHOD_END
1270 };
1271 AC97_DECLARE(agg_ac97);
1272 
1273 
1274 /* -------------------------------------------------------------------- */
1275 
1276 /* Playback channel. */
1277 
1278 static void *
1279 aggpch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
1280 {
1281 	struct agg_info *ess = devinfo;
1282 	struct agg_chinfo *ch;
1283 	bus_addr_t physaddr;
1284 	void *p;
1285 
1286 	KASSERT((dir == PCMDIR_PLAY),
1287 	    ("aggpch_init() called for RECORDING channel!"));
1288 	ch = ess->pch + ess->playchns;
1289 
1290 	ch->parent = ess;
1291 	ch->channel = c;
1292 	ch->buffer = b;
1293 	ch->num = ess->playchns;
1294 
1295 	p = dma_malloc(ess->buf_dmat, ess->bufsz, &physaddr);
1296 	if (p == NULL)
1297 		return NULL;
1298 	ch->phys = physaddr;
1299 	ch->base = physaddr & ((~(bus_addr_t)0) << WAVCACHE_BASEADDR_SHIFT);
1300 
1301 	sndbuf_setup(b, p, ess->bufsz);
1302 	ch->blklen = sndbuf_getblksz(b) / 2;
1303 	ch->buflen = sndbuf_getsize(b) / 2;
1304 	ess->playchns++;
1305 
1306 	return ch;
1307 }
1308 
1309 static void
1310 adjust_pchbase(struct agg_chinfo *chans, u_int n, u_int size)
1311 {
1312 	struct agg_chinfo *pchs[AGG_MAXPLAYCH];
1313 	u_int i, j, k;
1314 	bus_addr_t base;
1315 
1316 	/* sort pchs by phys address */
1317 	for (i = 0; i < n; i++) {
1318 		for (j = 0; j < i; j++)
1319 			if (chans[i].phys < pchs[j]->phys) {
1320 				for (k = i; k > j; k--)
1321 					pchs[k] = pchs[k - 1];
1322 				break;
1323 			}
1324 		pchs[j] = chans + i;
1325 	}
1326 
1327 	/* use new base register if next buffer can not be addressed
1328 	   via current base. */
1329 #define BASE_SHIFT (WPWA_WTBAR_SHIFT(2) + 2 + 1)
1330 	base = pchs[0]->base;
1331 	for (k = 1, i = 1; i < n; i++) {
1332 		if (pchs[i]->phys + size - base >= 1 << BASE_SHIFT)
1333 			/* not addressable: assign new base */
1334 			base = (pchs[i]->base -= k++ << BASE_SHIFT);
1335 		else
1336 			pchs[i]->base = base;
1337 	}
1338 #undef BASE_SHIFT
1339 
1340 	if (bootverbose) {
1341 		kprintf("Total of %d bases are assigned.\n", k);
1342 		for (i = 0; i < n; i++) {
1343 			kprintf("ch.%d: phys 0x%llx, wpwa 0x%llx\n",
1344 			       i, (long long)chans[i].phys,
1345 			       (long long)(chans[i].phys -
1346 					   chans[i].base) >> 1);
1347 		}
1348 	}
1349 }
1350 
1351 static int
1352 aggpch_free(kobj_t obj, void *data)
1353 {
1354 	struct agg_chinfo *ch = data;
1355 	struct agg_info *ess = ch->parent;
1356 
1357 	/* kfree up buffer - called after channel stopped */
1358 	dma_free(ess->buf_dmat, sndbuf_getbuf(ch->buffer));
1359 
1360 	/* return 0 if ok */
1361 	return 0;
1362 }
1363 
1364 static int
1365 aggpch_setformat(kobj_t obj, void *data, u_int32_t format)
1366 {
1367 	struct agg_chinfo *ch = data;
1368 
1369 	if (format & AFMT_BIGENDIAN || format & AFMT_U16_LE)
1370 		return EINVAL;
1371 	ch->stereo = ch->qs16 = ch->us = 0;
1372 	if (format & AFMT_STEREO)
1373 		ch->stereo = 1;
1374 
1375 	if (format & AFMT_U8 || format & AFMT_S8) {
1376 		if (format & AFMT_U8)
1377 			ch->us = 1;
1378 	} else
1379 		ch->qs16 = 1;
1380 	return 0;
1381 }
1382 
1383 static int
1384 aggpch_setspeed(kobj_t obj, void *data, u_int32_t speed)
1385 {
1386 	return ((struct agg_chinfo*)data)->speed = speed;
1387 }
1388 
1389 static int
1390 aggpch_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
1391 {
1392 	struct agg_chinfo *ch = data;
1393 	int blkcnt;
1394 
1395 	/* try to keep at least 20msec DMA space */
1396 	blkcnt = (ch->speed << (ch->stereo + ch->qs16)) / (50 * blocksize);
1397 	RANGE(blkcnt, 2, ch->parent->bufsz / blocksize);
1398 
1399 	if (sndbuf_getsize(ch->buffer) != blkcnt * blocksize) {
1400 		sndbuf_resize(ch->buffer, blkcnt, blocksize);
1401 		blkcnt = sndbuf_getblkcnt(ch->buffer);
1402 		blocksize = sndbuf_getblksz(ch->buffer);
1403 	} else {
1404 		sndbuf_setblkcnt(ch->buffer, blkcnt);
1405 		sndbuf_setblksz(ch->buffer, blocksize);
1406 	}
1407 
1408 	ch->blklen = blocksize / 2;
1409 	ch->buflen = blkcnt * blocksize / 2;
1410 	return blocksize;
1411 }
1412 
1413 static int
1414 aggpch_trigger(kobj_t obj, void *data, int go)
1415 {
1416 	struct agg_chinfo *ch = data;
1417 
1418 	switch (go) {
1419 	case PCMTRIG_EMLDMAWR:
1420 		break;
1421 	case PCMTRIG_START:
1422 		aggch_start_dac(ch);
1423 		break;
1424 	case PCMTRIG_ABORT:
1425 	case PCMTRIG_STOP:
1426 		aggch_stop_dac(ch);
1427 		break;
1428 	}
1429 	return 0;
1430 }
1431 
1432 static int
1433 aggpch_getptr(kobj_t obj, void *data)
1434 {
1435 	struct agg_chinfo *ch = data;
1436 	u_int cp;
1437 
1438 	agg_lock(ch->parent);
1439 	cp = wp_rdapu(ch->parent, (ch->num << 1) | 32, APUREG_CURPTR);
1440 	agg_unlock(ch->parent);
1441 
1442 	return ch->qs16 && ch->stereo
1443 		? (cp << 2) - ((0xffff << 2) & (ch->phys - ch->base))
1444 		: (cp << 1) - ((0xffff << 1) & (ch->phys - ch->base));
1445 }
1446 
1447 static struct pcmchan_caps *
1448 aggpch_getcaps(kobj_t obj, void *data)
1449 {
1450 	static u_int32_t playfmt[] = {
1451 		AFMT_U8,
1452 		AFMT_STEREO | AFMT_U8,
1453 		AFMT_S8,
1454 		AFMT_STEREO | AFMT_S8,
1455 		AFMT_S16_LE,
1456 		AFMT_STEREO | AFMT_S16_LE,
1457 		0
1458 	};
1459 	static struct pcmchan_caps playcaps = {8000, 48000, playfmt, 0};
1460 
1461 	return &playcaps;
1462 }
1463 
1464 
1465 static kobj_method_t aggpch_methods[] = {
1466     	KOBJMETHOD(channel_init,		aggpch_init),
1467     	KOBJMETHOD(channel_free,		aggpch_free),
1468     	KOBJMETHOD(channel_setformat,		aggpch_setformat),
1469     	KOBJMETHOD(channel_setspeed,		aggpch_setspeed),
1470     	KOBJMETHOD(channel_setblocksize,	aggpch_setblocksize),
1471     	KOBJMETHOD(channel_trigger,		aggpch_trigger),
1472     	KOBJMETHOD(channel_getptr,		aggpch_getptr),
1473     	KOBJMETHOD(channel_getcaps,		aggpch_getcaps),
1474 	KOBJMETHOD_END
1475 };
1476 CHANNEL_DECLARE(aggpch);
1477 
1478 
1479 /* -------------------------------------------------------------------- */
1480 
1481 /* Recording channel. */
1482 
1483 static void *
1484 aggrch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
1485 {
1486 	struct agg_info *ess = devinfo;
1487 	struct agg_rchinfo *ch;
1488 	u_int8_t *p;
1489 
1490 	KASSERT((dir == PCMDIR_REC),
1491 	    ("aggrch_init() called for PLAYBACK channel!"));
1492 	ch = &ess->rch;
1493 
1494 	ch->parent = ess;
1495 	ch->channel = c;
1496 	ch->buffer = b;
1497 
1498 	/* Uses the bottom-half of the status buffer. */
1499 	p        = ess->stat + ess->bufsz;
1500 	ch->phys = ess->phys + ess->bufsz;
1501 	ch->base = ess->phys;
1502 	ch->src  = (int16_t *)(p + ess->bufsz);
1503 	ch->srcphys = ch->phys + ess->bufsz;
1504 	ch->sink = (int16_t *)p;
1505 
1506 	sndbuf_setup(b, p, ess->bufsz);
1507 	ch->blklen = sndbuf_getblksz(b) / 2;
1508 	ch->buflen = sndbuf_getsize(b) / 2;
1509 
1510 	return ch;
1511 }
1512 
1513 static int
1514 aggrch_setformat(kobj_t obj, void *data, u_int32_t format)
1515 {
1516 	struct agg_rchinfo *ch = data;
1517 
1518 	if (!(format & AFMT_S16_LE))
1519 		return EINVAL;
1520 	if (format & AFMT_STEREO)
1521 		ch->stereo = 1;
1522 	else
1523 		ch->stereo = 0;
1524 	return 0;
1525 }
1526 
1527 static int
1528 aggrch_setspeed(kobj_t obj, void *data, u_int32_t speed)
1529 {
1530 	return ((struct agg_rchinfo*)data)->speed = speed;
1531 }
1532 
1533 static int
1534 aggrch_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
1535 {
1536 	struct agg_rchinfo *ch = data;
1537 	int blkcnt;
1538 
1539 	/* try to keep at least 20msec DMA space */
1540 	blkcnt = (ch->speed << ch->stereo) / (25 * blocksize);
1541 	RANGE(blkcnt, 2, ch->parent->bufsz / blocksize);
1542 
1543 	if (sndbuf_getsize(ch->buffer) != blkcnt * blocksize) {
1544 		sndbuf_resize(ch->buffer, blkcnt, blocksize);
1545 		blkcnt = sndbuf_getblkcnt(ch->buffer);
1546 		blocksize = sndbuf_getblksz(ch->buffer);
1547 	} else {
1548 		sndbuf_setblkcnt(ch->buffer, blkcnt);
1549 		sndbuf_setblksz(ch->buffer, blocksize);
1550 	}
1551 
1552 	ch->blklen = blocksize / 2;
1553 	ch->buflen = blkcnt * blocksize / 2;
1554 	return blocksize;
1555 }
1556 
1557 static int
1558 aggrch_trigger(kobj_t obj, void *sc, int go)
1559 {
1560 	struct agg_rchinfo *ch = sc;
1561 
1562 	switch (go) {
1563 	case PCMTRIG_EMLDMARD:
1564 		if (ch->stereo)
1565 			aggch_feed_adc_stereo(ch);
1566 		else
1567 			aggch_feed_adc_mono(ch);
1568 		break;
1569 	case PCMTRIG_START:
1570 		aggch_start_adc(ch);
1571 		break;
1572 	case PCMTRIG_ABORT:
1573 	case PCMTRIG_STOP:
1574 		aggch_stop_adc(ch);
1575 		break;
1576 	}
1577 	return 0;
1578 }
1579 
1580 static int
1581 aggrch_getptr(kobj_t obj, void *sc)
1582 {
1583 	struct agg_rchinfo *ch = sc;
1584 
1585 	return ch->stereo? ch->hwptr << 2 : ch->hwptr << 1;
1586 }
1587 
1588 static struct pcmchan_caps *
1589 aggrch_getcaps(kobj_t obj, void *sc)
1590 {
1591 	static u_int32_t recfmt[] = {
1592 		AFMT_S16_LE,
1593 		AFMT_STEREO | AFMT_S16_LE,
1594 		0
1595 	};
1596 	static struct pcmchan_caps reccaps = {8000, 48000, recfmt, 0};
1597 
1598 	return &reccaps;
1599 }
1600 
1601 static kobj_method_t aggrch_methods[] = {
1602 	KOBJMETHOD(channel_init,		aggrch_init),
1603 	/* channel_free: no-op */
1604 	KOBJMETHOD(channel_setformat,		aggrch_setformat),
1605 	KOBJMETHOD(channel_setspeed,		aggrch_setspeed),
1606 	KOBJMETHOD(channel_setblocksize,	aggrch_setblocksize),
1607 	KOBJMETHOD(channel_trigger,		aggrch_trigger),
1608 	KOBJMETHOD(channel_getptr,		aggrch_getptr),
1609 	KOBJMETHOD(channel_getcaps,		aggrch_getcaps),
1610 	KOBJMETHOD_END
1611 };
1612 CHANNEL_DECLARE(aggrch);
1613 
1614 
1615 /* -----------------------------
1616  * Bus space.
1617  */
1618 
1619 static void
1620 agg_intr(void *sc)
1621 {
1622 	struct agg_info* ess = sc;
1623 	register u_int8_t status;
1624 	int i;
1625 	u_int m;
1626 
1627 	status = AGG_RD(ess, PORT_HOSTINT_STAT, 1);
1628 	if (!status)
1629 		return;
1630 
1631 	/* Acknowledge intr. */
1632 	AGG_WR(ess, PORT_HOSTINT_STAT, status, 1);
1633 
1634 	if (status & HOSTINT_STAT_DSOUND) {
1635 #ifdef AGG_JITTER_CORRECTION
1636 		agg_lock(ess);
1637 #endif
1638 		if (ess->curpwr <= PCI_POWERSTATE_D1) {
1639 			AGG_WR(ess, PORT_INT_STAT, 1, 2);
1640 #ifdef AGG_JITTER_CORRECTION
1641 			for (i = 0, m = 1; i < ess->playchns; i++, m <<= 1) {
1642 				if (ess->active & m)
1643 					suppress_jitter(ess->pch + i);
1644 			}
1645 			if (ess->active & m)
1646 				suppress_rec_jitter(&ess->rch);
1647 			agg_unlock(ess);
1648 #endif
1649 			for (i = 0, m = 1; i < ess->playchns; i++, m <<= 1) {
1650 				if (ess->active & m) {
1651 					if (ess->curpwr <= PCI_POWERSTATE_D1)
1652 						chn_intr(ess->pch[i].channel);
1653 					else {
1654 						m = 0;
1655 						break;
1656 					}
1657 				}
1658 			}
1659 			if ((ess->active & m)
1660 			    && ess->curpwr <= PCI_POWERSTATE_D1)
1661 				chn_intr(ess->rch.channel);
1662 		}
1663 #ifdef AGG_JITTER_CORRECTION
1664 		else
1665 			agg_unlock(ess);
1666 #endif
1667 	}
1668 
1669 	if (status & HOSTINT_STAT_HWVOL) {
1670 		register u_int8_t event;
1671 
1672 		agg_lock(ess);
1673 		event = AGG_RD(ess, PORT_HWVOL_MASTER, 1);
1674 		AGG_WR(ess, PORT_HWVOL_MASTER, HWVOL_NOP, 1);
1675 		agg_unlock(ess);
1676 
1677 		switch (event) {
1678 		case HWVOL_UP:
1679 			mixer_hwvol_step(ess->dev, 1, 1);
1680 			break;
1681 		case HWVOL_DOWN:
1682 			mixer_hwvol_step(ess->dev, -1, -1);
1683 			break;
1684 		case HWVOL_NOP:
1685 			break;
1686 		default:
1687 			if (event & HWVOL_MUTE) {
1688 				mixer_hwvol_mute(ess->dev);
1689 				break;
1690 			}
1691 			device_printf(ess->dev,
1692 				      "%s: unknown HWVOL event 0x%x\n",
1693 				      device_get_nameunit(ess->dev), event);
1694 		}
1695 	}
1696 }
1697 
1698 static void
1699 setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1700 {
1701 	bus_addr_t *phys = arg;
1702 
1703 	*phys = error? 0 : segs->ds_addr;
1704 
1705 	if (bootverbose) {
1706 		kprintf("setmap (%lx, %lx), nseg=%d, error=%d\n",
1707 		    (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len,
1708 		    nseg, error);
1709 	}
1710 }
1711 
1712 static void *
1713 dma_malloc(bus_dma_tag_t dmat, u_int32_t sz, bus_addr_t *phys)
1714 {
1715 	void *buf;
1716 	bus_dmamap_t map;
1717 
1718 	if (bus_dmamem_alloc(dmat, &buf, BUS_DMA_NOWAIT, &map))
1719 		return NULL;
1720 	if (bus_dmamap_load(dmat, map, buf, sz, setmap, phys, 0)
1721 	    || !*phys || map) {
1722 		bus_dmamem_free(dmat, buf, map);
1723 		return NULL;
1724 	}
1725 	return buf;
1726 }
1727 
1728 static void
1729 dma_free(bus_dma_tag_t dmat, void *buf)
1730 {
1731 	bus_dmamem_free(dmat, buf, NULL);
1732 }
1733 
1734 static int
1735 agg_probe(device_t dev)
1736 {
1737 	char *s = NULL;
1738 
1739 	switch (pci_get_devid(dev)) {
1740 	case MAESTRO_1_PCI_ID:
1741 		s = "ESS Technology Maestro-1";
1742 		break;
1743 
1744 	case MAESTRO_2_PCI_ID:
1745 		s = "ESS Technology Maestro-2";
1746 		break;
1747 
1748 	case MAESTRO_2E_PCI_ID:
1749 		s = "ESS Technology Maestro-2E";
1750 		break;
1751 	}
1752 
1753 	if (s != NULL && pci_get_class(dev) == PCIC_MULTIMEDIA) {
1754 		device_set_desc(dev, s);
1755 		return BUS_PROBE_DEFAULT;
1756 	}
1757 	return ENXIO;
1758 }
1759 
1760 static int
1761 agg_attach(device_t dev)
1762 {
1763 	struct agg_info	*ess = NULL;
1764 	u_int32_t	data;
1765 	int	regid = PCIR_BAR(0);
1766 	struct resource	*reg = NULL;
1767 	struct ac97_info	*codec = NULL;
1768 	int	irqid = 0;
1769 	struct resource	*irq = NULL;
1770 	void	*ih = NULL;
1771 	char	status[SND_STATUSLEN];
1772 	int	ret = 0;
1773 
1774 	ess = kmalloc(sizeof *ess, M_DEVBUF, M_WAITOK | M_ZERO);
1775 	ess->dev = dev;
1776 
1777 #ifdef USING_MUTEX
1778 	ess->lock = snd_mtxcreate(device_get_desc(dev), "hardware status lock");
1779 	if (ess->lock == NULL) {
1780 		device_printf(dev, "failed to create a mutex.\n");
1781 		ret = ENOMEM;
1782 		goto bad;
1783 	}
1784 #endif
1785 
1786 	ess->bufsz = pcm_getbuffersize(dev, 4096, AGG_DEFAULT_BUFSZ, 65536);
1787 	if (bus_dma_tag_create(/*parent*/ NULL,
1788 			       /*align */ 4, 1 << (16+1),
1789 			       /*limit */ MAESTRO_MAXADDR, BUS_SPACE_MAXADDR,
1790 			       /*filter*/ NULL, NULL,
1791 			       /*size  */ ess->bufsz, 1, 0x3ffff,
1792 			       /*flags */ 0,
1793 			       &ess->buf_dmat) != 0) {
1794 		device_printf(dev, "unable to create dma tag\n");
1795 		ret = ENOMEM;
1796 		goto bad;
1797 	}
1798 
1799 	if (bus_dma_tag_create(/*parent*/NULL,
1800 			       /*align */ 1 << WAVCACHE_BASEADDR_SHIFT,
1801 			                  1 << (16+1),
1802 			       /*limit */ MAESTRO_MAXADDR, BUS_SPACE_MAXADDR,
1803 			       /*filter*/ NULL, NULL,
1804 			       /*size  */ 3*ess->bufsz, 1, 0x3ffff,
1805 			       /*flags */ 0,
1806 			       &ess->stat_dmat) != 0) {
1807 		device_printf(dev, "unable to create dma tag\n");
1808 		ret = ENOMEM;
1809 		goto bad;
1810 	}
1811 
1812 	/* Allocate the room for brain-damaging status buffer. */
1813 	ess->stat = dma_malloc(ess->stat_dmat, 3*ess->bufsz, &ess->phys);
1814 	if (ess->stat == NULL) {
1815 		device_printf(dev, "cannot allocate status buffer\n");
1816 		ret = ENOMEM;
1817 		goto bad;
1818 	}
1819 	if (bootverbose)
1820 		device_printf(dev, "Maestro status/record buffer: %#llx\n",
1821 		    (long long)ess->phys);
1822 
1823 	/* State D0-uninitialized. */
1824 	ess->curpwr = PCI_POWERSTATE_D3;
1825 	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
1826 
1827 	data = pci_read_config(dev, PCIR_COMMAND, 2);
1828 	data |= (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN);
1829 	pci_write_config(dev, PCIR_COMMAND, data, 2);
1830 	data = pci_read_config(dev, PCIR_COMMAND, 2);
1831 
1832 	/* Allocate resources. */
1833 	if (data & PCIM_CMD_PORTEN)
1834 		reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &regid,
1835 		    RF_ACTIVE);
1836 	if (reg != NULL) {
1837 		ess->reg = reg;
1838 		ess->regid = regid;
1839 		ess->st = rman_get_bustag(reg);
1840 		ess->sh = rman_get_bushandle(reg);
1841 	} else {
1842 		device_printf(dev, "unable to map register space\n");
1843 		ret = ENXIO;
1844 		goto bad;
1845 	}
1846 	irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqid,
1847 	    RF_ACTIVE | RF_SHAREABLE);
1848 	if (irq != NULL) {
1849 		ess->irq = irq;
1850 		ess->irqid = irqid;
1851 	} else {
1852 		device_printf(dev, "unable to map interrupt\n");
1853 		ret = ENXIO;
1854 		goto bad;
1855 	}
1856 
1857 	/* Setup resources. */
1858 	if (snd_setup_intr(dev, irq, INTR_MPSAFE, agg_intr, ess, &ih)) {
1859 		device_printf(dev, "unable to setup interrupt\n");
1860 		ret = ENXIO;
1861 		goto bad;
1862 	} else
1863 		ess->ih = ih;
1864 
1865 	/* Transition from D0-uninitialized to D0. */
1866 	agg_lock(ess);
1867 	agg_power(ess, PCI_POWERSTATE_D0);
1868 	if (agg_rdcodec(ess, 0) == 0x80) {
1869 		/* XXX - TODO: PT101 */
1870 		agg_unlock(ess);
1871 		device_printf(dev, "PT101 codec detected!\n");
1872 		ret = ENXIO;
1873 		goto bad;
1874 	}
1875 	agg_unlock(ess);
1876 	codec = AC97_CREATE(dev, ess, agg_ac97);
1877 	if (codec == NULL) {
1878 		device_printf(dev, "failed to create AC97 codec softc!\n");
1879 		ret = ENOMEM;
1880 		goto bad;
1881 	}
1882 	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) {
1883 		device_printf(dev, "mixer initialization failed!\n");
1884 		ret = ENXIO;
1885 		goto bad;
1886 	}
1887 	ess->codec = codec;
1888 
1889 	ret = pcm_register(dev, ess, AGG_MAXPLAYCH, 1);
1890 	if (ret)
1891 		goto bad;
1892 
1893 	mixer_hwvol_init(dev);
1894 	agg_lock(ess);
1895 	agg_power(ess, powerstate_init);
1896 	agg_unlock(ess);
1897 	for (data = 0; data < AGG_MAXPLAYCH; data++)
1898 		pcm_addchan(dev, PCMDIR_PLAY, &aggpch_class, ess);
1899 	pcm_addchan(dev, PCMDIR_REC, &aggrch_class, ess);
1900 	adjust_pchbase(ess->pch, ess->playchns, ess->bufsz);
1901 
1902 	ksnprintf(status, SND_STATUSLEN,
1903 	    "port 0x%lx-0x%lx irq %ld at device %d.%d on pci%d",
1904 	    rman_get_start(reg), rman_get_end(reg), rman_get_start(irq),
1905 	    pci_get_slot(dev), pci_get_function(dev), pci_get_bus(dev));
1906 	pcm_setstatus(dev, status);
1907 
1908 	return 0;
1909 
1910  bad:
1911 	if (codec != NULL)
1912 		ac97_destroy(codec);
1913 	if (ih != NULL)
1914 		bus_teardown_intr(dev, irq, ih);
1915 	if (irq != NULL)
1916 		bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
1917 	if (reg != NULL)
1918 		bus_release_resource(dev, SYS_RES_IOPORT, regid, reg);
1919 	if (ess != NULL) {
1920 		if (ess->stat != NULL)
1921 			dma_free(ess->stat_dmat, ess->stat);
1922 		if (ess->stat_dmat != NULL)
1923 			bus_dma_tag_destroy(ess->stat_dmat);
1924 		if (ess->buf_dmat != NULL)
1925 			bus_dma_tag_destroy(ess->buf_dmat);
1926 #ifdef USING_MUTEX
1927 		if (ess->lock != NULL)
1928 			snd_mtxfree(ess->lock);
1929 #endif
1930 		kfree(ess, M_DEVBUF);
1931 	}
1932 
1933 	return ret;
1934 }
1935 
1936 static int
1937 agg_detach(device_t dev)
1938 {
1939 	struct agg_info	*ess = pcm_getdevinfo(dev);
1940 	int r;
1941 	u_int16_t icr;
1942 
1943 	icr = AGG_RD(ess, PORT_HOSTINT_CTRL, 2);
1944 	AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
1945 
1946 	agg_lock(ess);
1947 	if (ess->active) {
1948 		AGG_WR(ess, PORT_HOSTINT_CTRL, icr, 2);
1949 		agg_unlock(ess);
1950 		return EBUSY;
1951 	}
1952 	agg_unlock(ess);
1953 
1954 	r = pcm_unregister(dev);
1955 	if (r) {
1956 		AGG_WR(ess, PORT_HOSTINT_CTRL, icr, 2);
1957 		return r;
1958 	}
1959 
1960 	agg_lock(ess);
1961 	agg_power(ess, PCI_POWERSTATE_D3);
1962 	agg_unlock(ess);
1963 
1964 	bus_teardown_intr(dev, ess->irq, ess->ih);
1965 	bus_release_resource(dev, SYS_RES_IRQ, ess->irqid, ess->irq);
1966 	bus_release_resource(dev, SYS_RES_IOPORT, ess->regid, ess->reg);
1967 	dma_free(ess->stat_dmat, ess->stat);
1968 	bus_dma_tag_destroy(ess->stat_dmat);
1969 	bus_dma_tag_destroy(ess->buf_dmat);
1970 #ifdef USING_MUTEX
1971 	snd_mtxfree(ess->lock);
1972 #endif
1973 	kfree(ess, M_DEVBUF);
1974 	return 0;
1975 }
1976 
1977 static int
1978 agg_suspend(device_t dev)
1979 {
1980 	struct agg_info *ess = pcm_getdevinfo(dev);
1981 #ifndef USING_MUTEX
1982 	int x;
1983 
1984 	x = spltty();
1985 #endif
1986 	AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
1987 	agg_lock(ess);
1988 	agg_power(ess, PCI_POWERSTATE_D3);
1989 	agg_unlock(ess);
1990 #ifndef USING_MUTEX
1991 	splx(x);
1992 #endif
1993 
1994 	return 0;
1995 }
1996 
1997 static int
1998 agg_resume(device_t dev)
1999 {
2000 	int i;
2001 	struct agg_info *ess = pcm_getdevinfo(dev);
2002 #ifndef USING_MUTEX
2003 	int x;
2004 
2005 	x = spltty();
2006 #endif
2007 	for (i = 0; i < ess->playchns; i++)
2008 		if (ess->active & (1 << i))
2009 			aggch_start_dac(ess->pch + i);
2010 	if (ess->active & (1 << i))
2011 		aggch_start_adc(&ess->rch);
2012 
2013 	agg_lock(ess);
2014 	if (!ess->active)
2015 		agg_power(ess, powerstate_init);
2016 	agg_unlock(ess);
2017 #ifndef USING_MUTEX
2018 	splx(x);
2019 #endif
2020 
2021 	if (mixer_reinit(dev)) {
2022 		device_printf(dev, "unable to reinitialize the mixer\n");
2023 		return ENXIO;
2024 	}
2025 
2026 	return 0;
2027 }
2028 
2029 static int
2030 agg_shutdown(device_t dev)
2031 {
2032 	struct agg_info *ess = pcm_getdevinfo(dev);
2033 
2034 	agg_lock(ess);
2035 	agg_power(ess, PCI_POWERSTATE_D3);
2036 	agg_unlock(ess);
2037 
2038 	return 0;
2039 }
2040 
2041 
2042 static device_method_t agg_methods[] = {
2043     DEVMETHOD(device_probe,	agg_probe),
2044     DEVMETHOD(device_attach,	agg_attach),
2045     DEVMETHOD(device_detach,	agg_detach),
2046     DEVMETHOD(device_suspend,	agg_suspend),
2047     DEVMETHOD(device_resume,	agg_resume),
2048     DEVMETHOD(device_shutdown,	agg_shutdown),
2049 
2050     DEVMETHOD_END
2051 };
2052 
2053 static driver_t agg_driver = {
2054     "pcm",
2055     agg_methods,
2056     PCM_SOFTC_SIZE,
2057 };
2058 
2059 /*static devclass_t pcm_devclass;*/
2060 
2061 DRIVER_MODULE(snd_maestro, pci, agg_driver, pcm_devclass, NULL, NULL);
2062 MODULE_DEPEND(snd_maestro, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
2063 MODULE_VERSION(snd_maestro, 1);
2064