xref: /openbsd-src/sys/dev/pci/maestro.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: maestro.c,v 1.27 2009/03/29 21:53:52 sthen Exp $	*/
2 /* $FreeBSD: /c/ncvs/src/sys/dev/sound/pci/maestro.c,v 1.3 2000/11/21 12:22:11 julian Exp $ */
3 /*
4  * FreeBSD's ESS Agogo/Maestro driver
5  * Converted from FreeBSD's pcm to OpenBSD's audio.
6  * Copyright (c) 2000, 2001 David Leonard & Marc Espie
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 /*-
31  * (FreeBSD) Credits:
32  * Copyright (c) 2000 Taku YAMAMOTO <taku@cent.saitama-u.ac.jp>
33  *
34  * Part of this code (especially in many magic numbers) was heavily inspired
35  * by the Linux driver originally written by
36  * Alan Cox <alan.cox@linux.org>, modified heavily by
37  * Zach Brown <zab@zabbo.net>.
38  *
39  * busdma()-ize and buffer size reduction were suggested by
40  * Cameron Grant <gandalf@vilnya.demon.co.uk>.
41  * Also he showed me the way to use busdma() suite.
42  *
43  * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500
44  * were looked at by
45  * Munehiro Matsuda <haro@tk.kubota.co.jp>,
46  * who brought patches based on the Linux driver with some simplification.
47  */
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/kernel.h>
52 #include <sys/malloc.h>
53 #include <sys/device.h>
54 #include <sys/proc.h>
55 #include <sys/queue.h>
56 #include <sys/fcntl.h>
57 
58 #include <dev/pci/pcidevs.h>
59 #include <dev/pci/pcivar.h>
60 
61 #include <sys/audioio.h>
62 #include <dev/audio_if.h>
63 #include <dev/mulaw.h>
64 #include <dev/auconv.h>
65 
66 #include <dev/ic/ac97.h>
67 
68 /* -----------------------------
69  * PCI config registers
70  */
71 
72 /* Legacy emulation */
73 #define CONF_LEGACY	0x40
74 
75 #define LEGACY_DISABLED	0x8000
76 
77 /* Chip configurations */
78 #define CONF_MAESTRO	0x50
79 #define MAESTRO_CHIBUS		0x00100000
80 #define MAESTRO_POSTEDWRITE	0x00000080
81 #define MAESTRO_DMA_PCITIMING	0x00000040
82 #define MAESTRO_SWAP_LR		0x00000010
83 
84 /* ACPI configurations */
85 #define CONF_ACPI_STOPCLOCK	0x54
86 #define ACPI_PART_2ndC_CLOCK	15
87 #define ACPI_PART_CODEC_CLOCK	14
88 #define ACPI_PART_978		13 /* Docking station or something */
89 #define ACPI_PART_SPDIF		12
90 #define ACPI_PART_GLUE		11 /* What? */
91 #define ACPI_PART_DAA		10
92 #define ACPI_PART_PCI_IF	9
93 #define ACPI_PART_HW_VOL	8
94 #define ACPI_PART_GPIO		7
95 #define ACPI_PART_ASSP		6
96 #define ACPI_PART_SB		5
97 #define ACPI_PART_FM		4
98 #define ACPI_PART_RINGBUS	3
99 #define ACPI_PART_MIDI		2
100 #define ACPI_PART_GAME_PORT	1
101 #define ACPI_PART_WP		0
102 
103 /* Power management */
104 #define	CONF_PM_PTR	0x34	/* BYTE R */
105 #define	PM_CID		0	/* BYTE R */
106 #define	PPMI_CID	1
107 #define	PM_CTRL		4	/* BYTE RW */
108 #define	PPMI_D0		0	/* Full power */
109 #define	PPMI_D1		1	/* Medium power */
110 #define	PPMI_D2		2	/* Low power */
111 #define	PPMI_D3		3	/* Turned off */
112 
113 
114 /* -----------------------------
115  * I/O ports
116  */
117 
118 /* Direct Sound Processor (aka Wave Processor) */
119 #define PORT_DSP_DATA	0x00	/* WORD RW */
120 #define PORT_DSP_INDEX	0x02	/* WORD RW */
121 #define PORT_INT_STAT	0x04	/* WORD RW */
122 #define PORT_SAMPLE_CNT	0x06	/* WORD RO */
123 
124 /* WaveCache */
125 #define PORT_WAVCACHE_INDEX	0x10	/* WORD RW */
126 #define PORT_WAVCACHE_DATA	0x12	/* WORD RW */
127 #define WAVCACHE_PCMBAR		0x1fc
128 #define WAVCACHE_WTBAR		0x1f0
129 #define WAVCACHE_BASEADDR_SHIFT	12
130 
131 #define WAVCACHE_CHCTL_ADDRTAG_MASK	0xfff8
132 #define WAVCACHE_CHCTL_U8		0x0004
133 #define WAVCACHE_CHCTL_STEREO		0x0002
134 #define WAVCACHE_CHCTL_DECREMENTAL	0x0001
135 
136 #define PORT_WAVCACHE_CTRL	0x14	/* WORD RW */
137 #define WAVCACHE_EXTRA_CH_ENABLED	0x0200
138 #define WAVCACHE_ENABLED		0x0100
139 #define WAVCACHE_CH_60_ENABLED		0x0080
140 #define WAVCACHE_WTSIZE_MASK	0x0060
141 #define WAVCACHE_WTSIZE_1MB	0x0000
142 #define WAVCACHE_WTSIZE_2MB	0x0020
143 #define WAVCACHE_WTSIZE_4MB	0x0040
144 #define WAVCACHE_WTSIZE_8MB	0x0060
145 #define WAVCACHE_SGC_MASK		0x000c
146 #define WAVCACHE_SGC_DISABLED		0x0000
147 #define WAVCACHE_SGC_40_47		0x0004
148 #define WAVCACHE_SGC_32_47		0x0008
149 #define WAVCACHE_TESTMODE		0x0001
150 
151 /* Host Interruption */
152 #define PORT_HOSTINT_CTRL	0x18	/* WORD RW */
153 #define HOSTINT_CTRL_SOFT_RESET		0x8000
154 #define HOSTINT_CTRL_DSOUND_RESET	0x4000
155 #define HOSTINT_CTRL_HW_VOL_TO_PME	0x0400
156 #define HOSTINT_CTRL_CLKRUN_ENABLED	0x0100
157 #define HOSTINT_CTRL_HWVOL_ENABLED	0x0040
158 #define HOSTINT_CTRL_ASSP_INT_ENABLED	0x0010
159 #define HOSTINT_CTRL_ISDN_INT_ENABLED	0x0008
160 #define HOSTINT_CTRL_DSOUND_INT_ENABLED	0x0004
161 #define HOSTINT_CTRL_MPU401_INT_ENABLED	0x0002
162 #define HOSTINT_CTRL_SB_INT_ENABLED	0x0001
163 
164 #define PORT_HOSTINT_STAT	0x1a	/* BYTE RW */
165 #define HOSTINT_STAT_HWVOL	0x40
166 #define HOSTINT_STAT_ASSP	0x10
167 #define HOSTINT_STAT_ISDN	0x08
168 #define HOSTINT_STAT_DSOUND	0x04
169 #define HOSTINT_STAT_MPU401	0x02
170 #define HOSTINT_STAT_SB		0x01
171 
172 /* Hardware volume */
173 #define PORT_HWVOL_VOICE_SHADOW	0x1c	/* BYTE RW */
174 #define PORT_HWVOL_VOICE	0x1d	/* BYTE RW */
175 #define PORT_HWVOL_MASTER_SHADOW 0x1e	/* BYTE RW */
176 #define PORT_HWVOL_MASTER	0x1f	/* BYTE RW */
177 
178 /* CODEC */
179 #define	PORT_CODEC_CMD	0x30	/* BYTE W */
180 #define CODEC_CMD_READ	0x80
181 #define	CODEC_CMD_WRITE	0x00
182 #define	CODEC_CMD_ADDR_MASK	0x7f
183 
184 #define PORT_CODEC_STAT	0x30	/* BYTE R */
185 #define CODEC_STAT_MASK	0x01
186 #define CODEC_STAT_RW_DONE	0x00
187 #define CODEC_STAT_PROGLESS	0x01
188 
189 #define PORT_CODEC_REG	0x32	/* WORD RW */
190 
191 /* Ring bus control */
192 #define PORT_RINGBUS_CTRL	0x34	/* DWORD RW */
193 #define RINGBUS_CTRL_I2S_ENABLED	0x80000000
194 #define RINGBUS_CTRL_RINGBUS_ENABLED	0x20000000
195 #define RINGBUS_CTRL_ACLINK_ENABLED	0x10000000
196 #define RINGBUS_CTRL_AC97_SWRESET	0x08000000
197 #define RINGBUS_CTRL_IODMA_PLAYBACK_ENABLED	0x04000000
198 #define RINGBUS_CTRL_IODMA_RECORD_ENABLED	0x02000000
199 
200 #define RINGBUS_SRC_MIC		20
201 #define RINGBUS_SRC_I2S		16
202 #define RINGBUS_SRC_ADC		12
203 #define RINGBUS_SRC_MODEM	8
204 #define RINGBUS_SRC_DSOUND	4
205 #define RINGBUS_SRC_ASSP	0
206 
207 #define RINGBUS_DEST_MONORAL	000
208 #define RINGBUS_DEST_STEREO	010
209 #define RINGBUS_DEST_NONE	0
210 #define RINGBUS_DEST_DAC	1
211 #define RINGBUS_DEST_MODEM_IN	2
212 #define RINGBUS_DEST_RESERVED3	3
213 #define RINGBUS_DEST_DSOUND_IN	4
214 #define RINGBUS_DEST_ASSP_IN	5
215 
216 /* General Purpose I/O */
217 #define PORT_GPIO_DATA	0x60	/* WORD RW */
218 #define PORT_GPIO_MASK	0x64	/* WORD RW */
219 #define PORT_GPIO_DIR	0x68	/* WORD RW */
220 
221 /* Application Specific Signal Processor */
222 #define PORT_ASSP_MEM_INDEX	0x80	/* DWORD RW */
223 #define PORT_ASSP_MEM_DATA	0x84	/* WORD RW */
224 #define PORT_ASSP_CTRL_A	0xa2	/* BYTE RW */
225 #define PORT_ASSP_CTRL_B	0xa4	/* BYTE RW */
226 #define PORT_ASSP_CTRL_C	0xa6	/* BYTE RW */
227 #define PORT_ASSP_HOST_WR_INDEX	0xa8	/* BYTE W */
228 #define PORT_ASSP_HOST_WR_DATA	0xaa	/* BYTE RW */
229 #define PORT_ASSP_INT_STAT	0xac	/* BYTE RW */
230 
231 
232 /* -----------------------------
233  * Wave Processor Indexed Data Registers.
234  */
235 
236 #define WPREG_DATA_PORT		0
237 #define WPREG_CRAM_PTR		1
238 #define WPREG_CRAM_DATA		2
239 #define WPREG_WAVE_DATA		3
240 #define WPREG_WAVE_PTR_LOW	4
241 #define WPREG_WAVE_PTR_HIGH	5
242 
243 #define WPREG_TIMER_FREQ	6
244 #define WP_TIMER_FREQ_PRESCALE_MASK	0x00e0	/* actual - 9 */
245 #define WP_TIMER_FREQ_PRESCALE_SHIFT	5
246 #define WP_TIMER_FREQ_DIVIDE_MASK	0x001f
247 #define WP_TIMER_FREQ_DIVIDE_SHIFT	0
248 
249 #define WPREG_WAVE_ROMRAM	7
250 #define WP_WAVE_VIRTUAL_ENABLED	0x0400
251 #define WP_WAVE_8BITRAM_ENABLED	0x0200
252 #define WP_WAVE_DRAM_ENABLED	0x0100
253 #define WP_WAVE_RAMSPLIT_MASK	0x00ff
254 #define WP_WAVE_RAMSPLIT_SHIFT	0
255 
256 #define WPREG_BASE		12
257 #define WP_PARAOUT_BASE_MASK	0xf000
258 #define WP_PARAOUT_BASE_SHIFT	12
259 #define WP_PARAIN_BASE_MASK	0x0f00
260 #define WP_PARAIN_BASE_SHIFT	8
261 #define WP_SERIAL0_BASE_MASK	0x00f0
262 #define WP_SERIAL0_BASE_SHIFT	4
263 #define WP_SERIAL1_BASE_MASK	0x000f
264 #define WP_SERIAL1_BASE_SHIFT	0
265 
266 #define WPREG_TIMER_ENABLE	17
267 #define WPREG_TIMER_START	23
268 
269 
270 /* -----------------------------
271  * Audio Processing Unit.
272  */
273 #define APUREG_APUTYPE	0
274 #define APU_DMA_ENABLED	0x4000
275 #define APU_INT_ON_LOOP	0x2000
276 #define APU_ENDCURVE	0x1000
277 #define APU_APUTYPE_MASK	0x00f0
278 #define APU_FILTERTYPE_MASK	0x000c
279 #define APU_FILTERQ_MASK	0x0003
280 
281 /* APU types */
282 #define APU_APUTYPE_SHIFT	4
283 
284 #define APUTYPE_INACTIVE	0
285 #define APUTYPE_16BITLINEAR	1
286 #define APUTYPE_16BITSTEREO	2
287 #define APUTYPE_8BITLINEAR	3
288 #define APUTYPE_8BITSTEREO	4
289 #define APUTYPE_8BITDIFF	5
290 #define APUTYPE_DIGITALDELAY	6
291 #define APUTYPE_DUALTAP_READER	7
292 #define APUTYPE_CORRELATOR	8
293 #define APUTYPE_INPUTMIXER	9
294 #define APUTYPE_WAVETABLE	10
295 #define APUTYPE_RATECONV	11
296 #define APUTYPE_16BITPINGPONG	12
297 /* APU type 13 through 15 are reserved. */
298 
299 /* Filter types */
300 #define APU_FILTERTYPE_SHIFT	2
301 
302 #define FILTERTYPE_2POLE_LOPASS		0
303 #define FILTERTYPE_2POLE_BANDPASS	1
304 #define FILTERTYPE_2POLE_HIPASS		2
305 #define FILTERTYPE_1POLE_LOPASS		3
306 #define FILTERTYPE_1POLE_HIPASS		4
307 #define FILTERTYPE_PASSTHROUGH		5
308 
309 /* Filter Q */
310 #define APU_FILTERQ_SHIFT	0
311 
312 #define FILTERQ_LESSQ	0
313 #define FILTERQ_MOREQ	3
314 
315 /* APU register 2 */
316 #define APUREG_FREQ_LOBYTE	2
317 #define APU_FREQ_LOBYTE_MASK	0xff00
318 #define APU_plus6dB		0x0010
319 
320 /* APU register 3 */
321 #define APUREG_FREQ_HIWORD	3
322 #define APU_FREQ_HIWORD_MASK	0x0fff
323 
324 /* Frequency */
325 #define APU_FREQ_LOBYTE_SHIFT	8
326 #define APU_FREQ_HIWORD_SHIFT	0
327 #define FREQ_Hz2DIV(freq)	(((u_int64_t)(freq) << 16) / 48000)
328 
329 /* APU register 4 */
330 #define APUREG_WAVESPACE	4
331 #define APU_STEREO		0x8000
332 #define APU_USE_SYSMEM		0x4000
333 #define APU_PCMBAR_MASK		0x6000
334 #define APU_64KPAGE_MASK	0xff00
335 
336 /* PCM Base Address Register selection */
337 #define APU_PCMBAR_SHIFT	13
338 
339 /* 64KW (==128KB) Page */
340 #define APU_64KPAGE_SHIFT	8
341 
342 /* APU register 5 - 7 */
343 #define APUREG_CURPTR	5
344 #define APUREG_ENDPTR	6
345 #define APUREG_LOOPLEN	7
346 
347 /* APU register 9 */
348 #define APUREG_AMPLITUDE	9
349 #define APU_AMPLITUDE_NOW_MASK	0xff00
350 #define APU_AMPLITUDE_DEST_MASK	0x00ff
351 
352 /* Amplitude now? */
353 #define APU_AMPLITUDE_NOW_SHIFT	8
354 
355 /* APU register 10 */
356 #define APUREG_POSITION	10
357 #define APU_RADIUS_MASK	0x00c0
358 #define APU_PAN_MASK	0x003f
359 
360 /* Radius control. */
361 #define APU_RADIUS_SHIFT	6
362 #define RADIUS_CENTERCIRCLE	0
363 #define RADIUS_MIDDLE		1
364 #define RADIUS_OUTSIDE		2
365 
366 /* Polar pan. */
367 #define APU_PAN_SHIFT	0
368 #define PAN_RIGHT	0x00
369 #define PAN_FRONT	0x08
370 #define PAN_LEFT	0x10
371 
372 
373 /* -----------------------------
374  * Limits.
375  */
376 #define WPWA_MAX	((1 << 22) - 1)
377 #define WPWA_MAXADDR	((1 << 23) - 1)
378 #define MAESTRO_MAXADDR	((1 << 28) - 1)
379 
380 
381 
382 #ifdef AUDIO_DEBUG
383 #define DPRINTF(x)	if (maestrodebug) printf x
384 #define DLPRINTF(i, x)	if (maestrodebug & i) printf x
385 int	maestrodebug = 0;
386 u_long maestrointr_called;
387 u_long maestrodma_effective;
388 
389 #define MAESTRODEBUG_INTR 1
390 #define MAESTRODEBUG_TIMER 2
391 #else
392 #define DPRINTF(x)
393 #define DLPRINTF(i, x)
394 #endif
395 
396 #define MAESTRO_BUFSIZ		0x4000
397 #define lengthof(array)		(sizeof (array) / sizeof (array)[0])
398 
399 #define STEP_VOLUME		0x22
400 #define MIDDLE_VOLUME		(STEP_VOLUME * 4)
401 
402 typedef struct salloc_pool {
403 	struct salloc_zone {
404 		SLIST_ENTRY(salloc_zone) link;
405 		caddr_t		addr;
406 		size_t		size;
407 	} *zones;
408 	SLIST_HEAD(salloc_head, salloc_zone) free, used, spare;
409 } *salloc_t;
410 
411 struct maestro_softc;
412 
413 #define MAESTRO_PLAY	1
414 #define MAESTRO_STEREO	2
415 #define MAESTRO_8BIT	4
416 #define MAESTRO_UNSIGNED	8
417 #define MAESTRO_RUNNING	16
418 
419 struct maestro_channel {
420 	struct maestro_softc 	*sc;
421 	int			num;
422 	u_int32_t		blocksize;
423 	u_int16_t		mode;
424 	u_int32_t		speed;
425 	u_int32_t		dv;
426 	u_int16_t		start;
427 	u_int16_t		threshold;
428 	u_int16_t		end;
429 	u_int16_t		current;
430 	u_int			wpwa;
431 	void			(*intr)(void *);
432 	void			*intr_arg;
433 };
434 
435 struct maestro_softc {
436 	struct device		dev;
437 
438 	void			*ih;
439 	pci_chipset_tag_t	pc;
440 	pcitag_t		pt;
441 
442 #define MAESTRO_FLAG_SETUPGPIO	0x0001
443 	int			flags;
444 	bus_space_tag_t		iot;
445 	bus_space_handle_t	ioh;
446 	bus_dma_tag_t		dmat;
447 
448 	caddr_t			dmabase;
449 	bus_addr_t		physaddr;
450 	size_t			dmasize;
451 	bus_dmamap_t		dmamap;
452 	bus_dma_segment_t	dmaseg;
453 	salloc_t		dmapool;
454 
455 	struct ac97_codec_if	*codec_if;
456 	struct ac97_host_if	host_if;
457 	struct audio_device	*sc_audev;
458 
459 	void			*powerhook;
460 	int			suspend;
461 
462 	struct maestro_channel	play;
463 	struct maestro_channel	record;
464 };
465 
466 
467 typedef	u_int16_t wpreg_t;
468 typedef	u_int16_t wcreg_t;
469 
470 salloc_t salloc_new(caddr_t, size_t, int);
471 void	salloc_destroy(salloc_t);
472 caddr_t	salloc_alloc(salloc_t, size_t);
473 void	salloc_free(salloc_t, caddr_t);
474 void	salloc_insert(salloc_t, struct salloc_head *,
475 		struct salloc_zone *, int);
476 
477 int	maestro_match(struct device *, void *, void *);
478 void	maestro_attach(struct device *, struct device *, void *);
479 int	maestro_intr(void *);
480 
481 int	maestro_open(void *, int);
482 void	maestro_close(void *);
483 int	maestro_query_encoding(void *, struct audio_encoding *);
484 int	maestro_set_params(void *, int, int, struct audio_params *,
485 			    struct audio_params *);
486 void	maestro_get_default_params(void *, int, struct audio_params *);
487 int	maestro_round_blocksize(void *, int);
488 int	maestro_halt_output(void *);
489 int	maestro_halt_input(void *);
490 int	maestro_getdev(void *, struct audio_device *);
491 int	maestro_set_port(void *, mixer_ctrl_t *);
492 int	maestro_get_port(void *, mixer_ctrl_t *);
493 int	maestro_query_devinfo(void *, mixer_devinfo_t *);
494 void	*maestro_malloc(void *, int, size_t, int, int);
495 void	maestro_free(void *, void *, int);
496 paddr_t	maestro_mappage(void *, void *, off_t, int);
497 int	maestro_get_props(void *);
498 int	maestro_trigger_output(void *, void *, void *, int, void (*)(void *),
499 				void *, struct audio_params *);
500 int	maestro_trigger_input(void *, void *, void *, int, void (*)(void *),
501 			       void *, struct audio_params *);
502 
503 int	maestro_attach_codec(void *, struct ac97_codec_if *);
504 enum ac97_host_flags maestro_codec_flags(void *);
505 int	maestro_read_codec(void *, u_int8_t, u_int16_t *);
506 int	maestro_write_codec(void *, u_int8_t, u_int16_t);
507 void	maestro_reset_codec(void *);
508 
509 void	maestro_initcodec(void *);
510 
511 void	maestro_set_speed(struct maestro_channel *, u_long *);
512 void	maestro_init(struct maestro_softc *);
513 void	maestro_power(struct maestro_softc *, int);
514 void	maestro_powerhook(int, void *);
515 
516 void 	maestro_channel_start(struct maestro_channel *);
517 void 	maestro_channel_stop(struct maestro_channel *);
518 void 	maestro_channel_advance_dma(struct maestro_channel *);
519 void	maestro_channel_suppress_jitter(struct maestro_channel *);
520 
521 int	maestro_get_flags(struct pci_attach_args *);
522 
523 void	ringbus_setdest(struct maestro_softc *, int, int);
524 
525 wpreg_t	wp_reg_read(struct maestro_softc *, int);
526 void	wp_reg_write(struct maestro_softc *, int, wpreg_t);
527 wpreg_t	wp_apu_read(struct maestro_softc *, int, int);
528 void	wp_apu_write(struct maestro_softc *, int, int, wpreg_t);
529 void	wp_settimer(struct maestro_softc *, u_int);
530 void	wp_starttimer(struct maestro_softc *);
531 void	wp_stoptimer(struct maestro_softc *);
532 
533 wcreg_t	wc_reg_read(struct maestro_softc *, int);
534 void	wc_reg_write(struct maestro_softc *, int, wcreg_t);
535 wcreg_t	wc_ctrl_read(struct maestro_softc *, int);
536 void	wc_ctrl_write(struct maestro_softc *, int, wcreg_t);
537 
538 u_int maestro_calc_timer_freq(struct maestro_channel *);
539 void maestro_update_timer(struct maestro_softc *);
540 
541 struct cfdriver maestro_cd = {
542 	NULL, "maestro", DV_DULL
543 };
544 
545 struct cfattach maestro_ca = {
546 	sizeof (struct maestro_softc), maestro_match, maestro_attach
547 };
548 
549 struct audio_hw_if maestro_hw_if = {
550 	maestro_open,
551 	maestro_close,
552 	NULL,
553 	maestro_query_encoding,
554 	maestro_set_params,
555 	maestro_round_blocksize,
556 	NULL,
557 	NULL,
558 	NULL,
559 	NULL,
560 	NULL,
561 	maestro_halt_output,
562 	maestro_halt_input,
563 	NULL,
564 	maestro_getdev,
565 	NULL,
566 	maestro_set_port,
567 	maestro_get_port,
568 	maestro_query_devinfo,
569 	maestro_malloc,
570 	maestro_free,
571 	NULL,
572 	maestro_mappage,
573 	maestro_get_props,
574 	maestro_trigger_output,
575 	maestro_trigger_input,
576 	maestro_get_default_params
577 };
578 
579 struct audio_device maestro_audev = {
580 	"ESS Maestro", "", "maestro"
581 };
582 
583 struct {
584 	u_short vendor, product;
585 	int flags;
586 } maestro_pcitab[] = {
587 	{ PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTROII,	0 },
588 	{ PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO2E,	0 },
589 	{ PCI_VENDOR_PLATFORM, PCI_PRODUCT_PLATFORM_ES1849,	0 },
590 	{ PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSAMAESTRO,		MAESTRO_FLAG_SETUPGPIO },
591 	{ PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSAPRONXVA26D,	MAESTRO_FLAG_SETUPGPIO }
592 };
593 #define NMAESTRO_PCITAB	lengthof(maestro_pcitab)
594 
595 int
596 maestro_get_flags(pa)
597 	struct pci_attach_args *pa;
598 {
599 	int i;
600 
601 	/* Distinguish audio devices from modems with the same manfid */
602 	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_MULTIMEDIA)
603 		return (-1);
604 	if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MULTIMEDIA_AUDIO)
605 		return (-1);
606 	for (i = 0; i < NMAESTRO_PCITAB; i++)
607 		if (PCI_VENDOR(pa->pa_id) == maestro_pcitab[i].vendor &&
608 		    PCI_PRODUCT(pa->pa_id) == maestro_pcitab[i].product)
609 			return (maestro_pcitab[i].flags);
610 	return (-1);
611 }
612 
613 /* -----------------------------
614  * Driver interface.
615  */
616 
617 int
618 maestro_match(parent, match, aux)
619 	struct device *parent;
620 	void *match;
621 	void *aux;
622 {
623 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
624 
625 	if (maestro_get_flags(pa) == -1)
626 		return (0);
627 	else
628 		return (1);
629 }
630 
631 void
632 maestro_attach(parent, self, aux)
633 	struct device *parent;
634 	struct device *self;
635 	void *aux;
636 {
637 	struct maestro_softc *sc = (struct maestro_softc *)self;
638 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
639 	pci_chipset_tag_t pc = pa->pa_pc;
640 	char const *intrstr;
641 	pci_intr_handle_t ih;
642 	int error;
643 	u_int16_t cdata;
644 	int dmastage = 0;
645 	int rseg;
646 
647 	sc->sc_audev = &maestro_audev;
648 	sc->flags = maestro_get_flags(pa);
649 
650 	sc->pc = pa->pa_pc;
651 	sc->pt = pa->pa_tag;
652 	sc->dmat = pa->pa_dmat;
653 
654 	/* Map interrupt */
655 	if (pci_intr_map(pa, &ih)) {
656 		printf(": can't map interrupt\n");
657 		return;
658 	}
659 	intrstr = pci_intr_string(pc, ih);
660 	sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, maestro_intr, sc,
661 	    sc->dev.dv_xname);
662 	if (sc->ih == NULL) {
663 		printf(": can't establish interrupt");
664 		if (intrstr != NULL)
665 			printf(" at %s\n", intrstr);
666 		return;
667 	}
668 	printf(": %s", intrstr);
669 
670 	/* Rangers, power up */
671 	maestro_power(sc, PPMI_D0);
672 	DELAY(100000);
673 
674 	/* Map i/o */
675 	if ((error = pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_IO,
676 	    0, &sc->iot, &sc->ioh, NULL, NULL, 0)) != 0) {
677 		printf(", can't map i/o space\n");
678 		goto bad;
679 	};
680 
681 	/* Allocate fixed DMA segment :-( */
682 	sc->dmasize = MAESTRO_BUFSIZ * 16;
683 	if ((error = bus_dmamem_alloc(sc->dmat, sc->dmasize, NBPG, 0,
684 	    &sc->dmaseg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
685 		printf(", unable to alloc dma, error %d\n", error);
686 		goto bad;
687 	}
688 	dmastage = 1;
689 	if ((error = bus_dmamem_map(sc->dmat, &sc->dmaseg, 1,
690 	    sc->dmasize, &sc->dmabase, BUS_DMA_NOWAIT |
691 	    BUS_DMA_COHERENT)) != 0) {
692 		printf(", unable to map dma, error %d\n", error);
693 		goto bad;
694 	}
695 	dmastage = 2;
696 	if ((error = bus_dmamap_create(sc->dmat, sc->dmasize, 1,
697 	    sc->dmasize, 0, BUS_DMA_NOWAIT, &sc->dmamap)) != 0) {
698 		printf(", unable to create dma map, error %d\n", error);
699 		goto bad;
700 	}
701 	dmastage = 3;
702 	if ((error = bus_dmamap_load(sc->dmat, sc->dmamap,
703 	    sc->dmabase, sc->dmasize, NULL, BUS_DMA_NOWAIT)) != 0) {
704 		printf(", unable to load dma map, error %d\n", error);
705 		goto bad;
706 	}
707 
708 	/* XXX
709 	 * The first byte of the allocated memory is not usable,
710 	 * the WP sometimes uses it to store status.
711 	 */
712 	/* Make DMA memory pool */
713 	if ((sc->dmapool = salloc_new(sc->dmabase+16, sc->dmasize-16,
714 	    128/*overkill?*/)) == NULL) {
715 		printf(", unable to make dma pool\n");
716 		goto bad;
717 	}
718 
719 	sc->physaddr = sc->dmamap->dm_segs[0].ds_addr;
720 
721 	printf("\n");
722 
723 	/* Kick device */
724 	maestro_init(sc);
725 	maestro_read_codec(sc, 0, &cdata);
726 	if (cdata == 0x80) {
727 		printf("%s: PT101 codec unsupported, no mixer\n",
728 		    sc->dev.dv_xname);
729 		/* Init values from Linux, no idea what this does. */
730 		maestro_write_codec(sc, 0x2a, 0x0001);
731 		maestro_write_codec(sc, 0x2C, 0x0000);
732 		maestro_write_codec(sc, 0x2C, 0xFFFF);
733 		maestro_write_codec(sc, 0x10, 0x9F1F);
734 		maestro_write_codec(sc, 0x12, 0x0808);
735 		maestro_write_codec(sc, 0x14, 0x9F1F);
736 		maestro_write_codec(sc, 0x16, 0x9F1F);
737 		maestro_write_codec(sc, 0x18, 0x0404);
738 		maestro_write_codec(sc, 0x1A, 0x0000);
739 		maestro_write_codec(sc, 0x1C, 0x0000);
740 		maestro_write_codec(sc, 0x02, 0x0404);
741 		maestro_write_codec(sc, 0x04, 0x0808);
742 		maestro_write_codec(sc, 0x0C, 0x801F);
743 		maestro_write_codec(sc, 0x0E, 0x801F);
744 		/* no control over the mixer, sorry */
745 		sc->codec_if = NULL;
746 	} else {
747 		/* Attach the AC'97 */
748 		sc->host_if.arg = sc;
749 		sc->host_if.attach = maestro_attach_codec;
750 		sc->host_if.flags = maestro_codec_flags;
751 		sc->host_if.read = maestro_read_codec;
752 		sc->host_if.write = maestro_write_codec;
753 		sc->host_if.reset = maestro_reset_codec;
754 		if (ac97_attach(&sc->host_if) != 0) {
755 			printf("%s: can't attach codec\n", sc->dev.dv_xname);
756 			goto bad;
757 		}
758 	}
759 
760 	sc->play.mode = MAESTRO_PLAY;
761 	sc->play.sc = sc;
762 	sc->play.num = 0;
763 	sc->record.sc = sc;
764 	sc->record.num = 2;
765 	sc->record.mode = 0;
766 
767 	/* Attach audio */
768 	audio_attach_mi(&maestro_hw_if, sc, &sc->dev);
769 
770 	/* Hook power changes */
771 	sc->suspend = PWR_RESUME;
772 	sc->powerhook = powerhook_establish(maestro_powerhook, sc);
773 
774 	return;
775 
776  bad:
777 	/* Power down. */
778 	maestro_power(sc, PPMI_D3);
779 	if (sc->ih)
780 		pci_intr_disestablish(pc, sc->ih);
781 	printf("%s: disabled\n", sc->dev.dv_xname);
782 	if (sc->dmapool)
783 		salloc_destroy(sc->dmapool);
784 	if (dmastage >= 3)
785 		bus_dmamap_destroy(sc->dmat, sc->dmamap);
786 	if (dmastage >= 2)
787 		bus_dmamem_unmap(sc->dmat, sc->dmabase, sc->dmasize);
788 	if (dmastage >= 1)
789 		bus_dmamem_free(sc->dmat, &sc->dmaseg, 1);
790 }
791 
792 void
793 maestro_init(sc)
794 	struct maestro_softc *sc;
795 {
796 	int reg;
797 	pcireg_t data;
798 
799 	/* Disable all legacy emulations. */
800 	data = pci_conf_read(sc->pc, sc->pt, CONF_LEGACY);
801 	data |= LEGACY_DISABLED;
802 	pci_conf_write(sc->pc, sc->pt, CONF_LEGACY, data);
803 
804 	/* Disconnect from CHI. (Makes Dell inspiron 7500 work?)
805 	 * Enable posted write.
806 	 * Prefer PCI timing rather than that of ISA.
807 	 * Don't swap L/R. */
808 	data = pci_conf_read(sc->pc, sc->pt, CONF_MAESTRO);
809 	data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING;
810 	data &= ~MAESTRO_SWAP_LR;
811 	pci_conf_write(sc->pc, sc->pt, CONF_MAESTRO, data);
812 	/* Reset direct sound. */
813 	bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL,
814 	    HOSTINT_CTRL_DSOUND_RESET);
815 	DELAY(10000);	/* XXX - too long? */
816 	bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 0);
817 	DELAY(10000);
818 
819 	/* Enable direct sound and hardware volume control interruptions. */
820 	bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL,
821 	    HOSTINT_CTRL_DSOUND_INT_ENABLED | HOSTINT_CTRL_HWVOL_ENABLED);
822 
823 	/* Setup Wave Processor. */
824 
825 	/* Enable WaveCache, set DMA base address. */
826 	wp_reg_write(sc, WPREG_WAVE_ROMRAM,
827 	    WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED);
828 	bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_CTRL,
829 	    WAVCACHE_ENABLED | WAVCACHE_WTSIZE_4MB);
830 
831 	for (reg = WAVCACHE_PCMBAR; reg < WAVCACHE_PCMBAR + 4; reg++)
832 		wc_reg_write(sc, reg,
833 			sc->physaddr >> WAVCACHE_BASEADDR_SHIFT);
834 
835 	/* Setup Codec/Ringbus. */
836 	maestro_initcodec(sc);
837 	bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL,
838 	    RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED);
839 
840 	wp_reg_write(sc, WPREG_BASE, 0x8500);	/* Parallel I/O */
841 	ringbus_setdest(sc, RINGBUS_SRC_ADC,
842 	    RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN);
843 	ringbus_setdest(sc, RINGBUS_SRC_DSOUND,
844 	    RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC);
845 
846 	/* Setup ASSP. Needed for Dell Inspiron 7500? */
847 	bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_B, 0x00);
848 	bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_A, 0x03);
849 	bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_C, 0x00);
850 
851 	/*
852 	 * Reset hw volume to a known value so that we may handle diffs
853 	 * off to AC'97.
854 	 */
855 
856 	bus_space_write_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER, MIDDLE_VOLUME);
857 	/* Setup GPIO if needed (NEC systems) */
858 	if (sc->flags & MAESTRO_FLAG_SETUPGPIO) {
859 		/* Matthew Braithwaite <matt@braithwaite.net> reported that
860 		 * NEC Versa LX doesn't need GPIO operation. */
861 		bus_space_write_2(sc->iot, sc->ioh,
862 		    PORT_GPIO_MASK, 0x9ff);
863 		bus_space_write_2(sc->iot, sc->ioh, PORT_GPIO_DIR,
864 		    bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DIR) | 0x600);
865 		bus_space_write_2(sc->iot, sc->ioh,
866 		    PORT_GPIO_DATA, 0x200);
867 	}
868 }
869 
870 /* -----------------------------
871  * Audio interface
872  */
873 
874 int
875 maestro_round_blocksize(self, blk)
876 	void *self;
877 	int blk;
878 {
879 	return ((blk + 0xf) & ~0xf);
880 }
881 
882 void *
883 maestro_malloc(arg, dir, size, pool, flags)
884 	void *arg;
885 	int dir;
886 	size_t size;
887 	int pool, flags;
888 {
889 	struct maestro_softc *sc = (struct maestro_softc *)arg;
890 
891 	return (salloc_alloc(sc->dmapool, size));
892 }
893 
894 void
895 maestro_free(self, ptr, pool)
896 	void *self, *ptr;
897 	int pool;
898 {
899 	struct maestro_softc *sc = (struct maestro_softc *)self;
900 
901 	salloc_free(sc->dmapool, ptr);
902 }
903 
904 paddr_t
905 maestro_mappage(self, mem, off, prot)
906 	void *self, *mem;
907 	off_t off;
908 	int prot;
909 {
910 	struct maestro_softc *sc = (struct maestro_softc *)self;
911 
912 	if (off < 0)
913 		return -1;
914 	return bus_dmamem_mmap(sc->dmat, &sc->dmaseg, 1,
915 		off, prot, BUS_DMA_WAITOK);
916 }
917 
918 int
919 maestro_get_props(self)
920 	void *self;
921 {
922 	/* struct maestro_softc *sc = (struct maestro_softc *)self; */
923 
924 	return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT); /* XXX */
925 }
926 
927 int
928 maestro_getdev(self, retp)
929 	void *self;
930 	struct audio_device *retp;
931 {
932 	struct maestro_softc *sc = (struct maestro_softc *)self;
933 
934 	*retp = *sc->sc_audev;
935 	return 0;
936 }
937 
938 int
939 maestro_set_port(self, cp)
940 	void *self;
941 	mixer_ctrl_t *cp;
942 {
943 	struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if;
944 
945 	if (c)
946 		return (c->vtbl->mixer_set_port(c, cp));
947 	else
948 		return (ENXIO);
949 }
950 
951 int
952 maestro_get_port(self, cp)
953 	void *self;
954 	mixer_ctrl_t *cp;
955 {
956 	struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if;
957 
958 	if (c)
959 		return (c->vtbl->mixer_get_port(c, cp));
960 	else
961 		return (ENXIO);
962 }
963 
964 int
965 maestro_query_devinfo(self, cp)
966 	void *self;
967 	mixer_devinfo_t *cp;
968 {
969 	struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if;
970 
971 	if (c)
972 		return (c->vtbl->query_devinfo(c, cp));
973 	else
974 		return (ENXIO);
975 }
976 
977 struct audio_encoding maestro_tab[] = {
978 	{0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0},
979 	{1, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0},
980 	{2, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0},
981 	{3, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16,
982 	    AUDIO_ENCODINGFLAG_EMULATED},
983 	{4, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16,
984 	    AUDIO_ENCODINGFLAG_EMULATED},
985 	{5, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16,
986 	    AUDIO_ENCODINGFLAG_EMULATED},
987 	{6, AudioEmulaw, AUDIO_ENCODING_ULAW, 8,
988 	    AUDIO_ENCODINGFLAG_EMULATED},
989 	{7, AudioEalaw, AUDIO_ENCODING_ALAW, 8,
990 	    AUDIO_ENCODINGFLAG_EMULATED}
991 };
992 
993 int
994 maestro_query_encoding(hdl, fp)
995 	void *hdl;
996 	struct audio_encoding *fp;
997 {
998 	if (fp->index < 0 || fp->index >= lengthof(maestro_tab))
999 		return (EINVAL);
1000 	*fp = maestro_tab[fp->index];
1001 	return (0);
1002 }
1003 
1004 void
1005 maestro_get_default_params(void *addr, int mode, struct audio_params *params)
1006 {
1007 	ac97_get_default_params(params);
1008 }
1009 
1010 #define UNUSED __attribute__((unused))
1011 
1012 void
1013 maestro_set_speed(ch, prate)
1014 	struct maestro_channel *ch;
1015 	u_long *prate;
1016 {
1017 	ch->speed = *prate;
1018 	if ((ch->mode & (MAESTRO_8BIT | MAESTRO_STEREO)) == MAESTRO_8BIT)
1019 		ch->speed /= 2;
1020 
1021 	/* special common case */
1022 	if (ch->speed == 48000) {
1023 		ch->dv = 0x10000;
1024 	} else {
1025 		/* compute 16 bits fixed point value of speed/48000,
1026 		 * being careful not to overflow */
1027 		 ch->dv = (((ch->speed % 48000) << 16U) + 24000) / 48000
1028 		    + ((ch->speed / 48000) << 16U);
1029 		/* And this is the real rate obtained */
1030 		ch->speed = (ch->dv >> 16U) * 48000 +
1031 		    (((ch->dv & 0xffff)*48000)>>16U);
1032 	}
1033 	*prate = ch->speed;
1034 	if ((ch->mode & (MAESTRO_8BIT | MAESTRO_STEREO)) == MAESTRO_8BIT)
1035 		*prate *= 2;
1036 }
1037 
1038 u_int
1039 maestro_calc_timer_freq(ch)
1040 	struct maestro_channel *ch;
1041 {
1042 	u_int	ss = 2;
1043 
1044 	if (ch->mode & MAESTRO_8BIT)
1045 		ss = 1;
1046 	return (ch->speed * ss) / ch->blocksize;
1047 }
1048 
1049 void
1050 maestro_update_timer(sc)
1051 	struct maestro_softc *sc;
1052 {
1053 	u_int freq = 0;
1054 	u_int n;
1055 
1056 	if (sc->play.mode & MAESTRO_RUNNING)
1057 		freq = maestro_calc_timer_freq(&sc->play);
1058 	if (sc->record.mode & MAESTRO_RUNNING) {
1059 		n = maestro_calc_timer_freq(&sc->record);
1060 		if (freq < n)
1061 			freq = n;
1062 	}
1063 	if (freq) {
1064 		wp_settimer(sc, freq);
1065 		wp_starttimer(sc);
1066     	} else
1067 		wp_stoptimer(sc);
1068 }
1069 
1070 
1071 int
1072 maestro_set_params(hdl, setmode, usemode, play, rec)
1073 	void *hdl;
1074 	int setmode, usemode;
1075 	struct audio_params *play, *rec;
1076 {
1077 	struct maestro_softc *sc = (struct maestro_softc *)hdl;
1078 
1079 	if ((setmode & AUMODE_PLAY) == 0)
1080 		return (0);
1081 
1082 	/* Disallow parameter change on a running audio for now */
1083 	if (sc->play.mode & MAESTRO_RUNNING)
1084 		return (EINVAL);
1085 
1086 	if (play->sample_rate < 4000)
1087 		play->sample_rate = 4000;
1088 	else if (play->sample_rate > 48000)
1089 		play->sample_rate = 48000;
1090 
1091 	play->factor = 1;
1092 	play->sw_code = NULL;
1093 	if (play->channels > 2)
1094 		play->channels = 2;
1095 
1096 	sc->play.mode = MAESTRO_PLAY;
1097 	if (play->channels == 2)
1098 		sc->play.mode |= MAESTRO_STEREO;
1099 
1100 	if (play->encoding == AUDIO_ENCODING_ULAW) {
1101 		play->factor = 2;
1102 		play->sw_code = mulaw_to_slinear16_le;
1103 	} else if (play->encoding == AUDIO_ENCODING_ALAW) {
1104 		play->factor = 2;
1105 		play->sw_code = alaw_to_slinear16_le;
1106 	} else if (play->precision == 8) {
1107 		sc->play.mode |= MAESTRO_8BIT;
1108 		if (play->encoding == AUDIO_ENCODING_ULINEAR_LE ||
1109 		    play->encoding == AUDIO_ENCODING_ULINEAR_BE)
1110 		    sc->play.mode |= MAESTRO_UNSIGNED;
1111 	}
1112 	else if (play->encoding == AUDIO_ENCODING_ULINEAR_LE)
1113 		play->sw_code = change_sign16_le;
1114 	else if (play->encoding == AUDIO_ENCODING_SLINEAR_BE)
1115 		play->sw_code = swap_bytes;
1116 	else if (play->encoding == AUDIO_ENCODING_ULINEAR_BE)
1117 		play->sw_code = change_sign16_swap_bytes_le;
1118 	else if (play->encoding != AUDIO_ENCODING_SLINEAR_LE)
1119 		return (EINVAL);
1120 
1121 	maestro_set_speed(&sc->play, &play->sample_rate);
1122 	return (0);
1123 }
1124 
1125 int
1126 maestro_open(hdl, flags)
1127 	void *hdl;
1128 	int flags;
1129 {
1130 	struct maestro_softc *sc = (struct maestro_softc *)hdl;
1131 	DPRINTF(("%s: open(%d)\n", sc->dev.dv_xname, flags));
1132 
1133 /* XXX work around VM brokeness */
1134 #if 0
1135 	if ((OFLAGS(flags) & O_ACCMODE) != O_WRONLY)
1136 		return (EINVAL);
1137 #endif
1138 	sc->play.mode = MAESTRO_PLAY;
1139 	sc->record.mode = 0;
1140 #ifdef AUDIO_DEBUG
1141 	maestrointr_called = 0;
1142 	maestrodma_effective = 0;
1143 #endif
1144 	return (0);
1145 }
1146 
1147 void
1148 maestro_close(hdl)
1149 	void *hdl;
1150 {
1151 	struct maestro_softc *sc UNUSED = (struct maestro_softc *)hdl;
1152 	/* nothing to do */
1153 }
1154 
1155 
1156 void
1157 maestro_channel_stop(ch)
1158 	struct maestro_channel *ch;
1159 {
1160 	wp_apu_write(ch->sc, ch->num, APUREG_APUTYPE,
1161 	    APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1162 	if (ch->mode & MAESTRO_STEREO)
1163 	    wp_apu_write(ch->sc, ch->num+1, APUREG_APUTYPE,
1164 		APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1165 	/* four channels for record... */
1166 	if (ch->mode & MAESTRO_PLAY)
1167 		return;
1168 	wp_apu_write(ch->sc, ch->num+2, APUREG_APUTYPE,
1169 	    APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1170 	if (ch->mode & MAESTRO_STEREO)
1171 	    wp_apu_write(ch->sc, ch->num+3, APUREG_APUTYPE,
1172 		APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1173 
1174 }
1175 
1176 int
1177 maestro_halt_input(hdl)
1178 	void *hdl;
1179 {
1180 	struct maestro_softc *sc = (struct maestro_softc *)hdl;
1181 	maestro_channel_stop(&sc->record);
1182 	sc->record.mode &= ~MAESTRO_RUNNING;
1183 	maestro_update_timer(sc);
1184 	return 0;
1185 }
1186 
1187 int
1188 maestro_halt_output(hdl)
1189 	void *hdl;
1190 {
1191 	struct maestro_softc *sc = (struct maestro_softc *)hdl;
1192 
1193 	maestro_channel_stop(&sc->play);
1194 	sc->play.mode &= ~MAESTRO_RUNNING;
1195 	maestro_update_timer(sc);
1196 	return 0;
1197 }
1198 
1199 int
1200 maestro_trigger_input(hdl, start, end, blksize, intr, arg, param)
1201 	void *hdl;
1202 	void *start, *end;
1203 	int blksize;
1204 	void (*intr)(void *);
1205 	void *arg;
1206 	struct audio_params *param;
1207 {
1208 	struct maestro_softc *sc = (struct maestro_softc *)hdl;
1209 
1210 	sc->record.mode |= MAESTRO_RUNNING;
1211 	sc->record.blocksize = blksize;
1212 
1213 	maestro_channel_start(&sc->record);
1214 
1215 	sc->record.threshold = sc->record.start;
1216 	maestro_update_timer(sc);
1217 	return 0;
1218 }
1219 
1220 void
1221 maestro_channel_start(ch)
1222 	struct maestro_channel *ch;
1223 {
1224 	struct maestro_softc *sc = ch->sc;
1225 	int n = ch->num;
1226 	int aputype;
1227 	wcreg_t wcreg = (sc->physaddr - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
1228 
1229 	switch(ch->mode & (MAESTRO_STEREO | MAESTRO_8BIT)) {
1230 	case 0:
1231 		aputype = APUTYPE_16BITLINEAR;
1232 		break;
1233 	case MAESTRO_STEREO:
1234 		aputype = APUTYPE_16BITSTEREO;
1235 		break;
1236 	case MAESTRO_8BIT:
1237 		aputype = APUTYPE_8BITLINEAR;
1238 		break;
1239 	case MAESTRO_8BIT|MAESTRO_STEREO:
1240 		aputype = APUTYPE_8BITSTEREO;
1241 		break;
1242 	}
1243 	if (ch->mode & MAESTRO_UNSIGNED)
1244 		wcreg |= WAVCACHE_CHCTL_U8;
1245 	if ((ch->mode & MAESTRO_STEREO) == 0) {
1246 		DPRINTF(("Setting mono parameters\n"));
1247 		wp_apu_write(sc, n, APUREG_WAVESPACE, ch->wpwa & 0xff00);
1248 		wp_apu_write(sc, n, APUREG_CURPTR, ch->current);
1249 		wp_apu_write(sc, n, APUREG_ENDPTR, ch->end);
1250 		wp_apu_write(sc, n, APUREG_LOOPLEN, ch->end - ch->start);
1251 		wp_apu_write(sc, n, APUREG_AMPLITUDE, 0xe800);
1252 		wp_apu_write(sc, n, APUREG_POSITION, 0x8f00
1253 		    | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT)
1254 		    | (PAN_FRONT << APU_PAN_SHIFT));
1255 		wp_apu_write(sc, n, APUREG_FREQ_LOBYTE, APU_plus6dB
1256 		    | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT));
1257 		wp_apu_write(sc, n, APUREG_FREQ_HIWORD, ch->dv >> 8);
1258 		wc_ctrl_write(sc, n, wcreg);
1259 		wp_apu_write(sc, n, APUREG_APUTYPE,
1260 		    (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1261 	} else {
1262 		wcreg |= WAVCACHE_CHCTL_STEREO;
1263 		DPRINTF(("Setting stereo parameters\n"));
1264 		wp_apu_write(sc, n+1, APUREG_WAVESPACE, ch->wpwa & 0xff00);
1265 		wp_apu_write(sc, n+1, APUREG_CURPTR, ch->current);
1266 		wp_apu_write(sc, n+1, APUREG_ENDPTR, ch->end);
1267 		wp_apu_write(sc, n+1, APUREG_LOOPLEN, ch->end - ch->start);
1268 		wp_apu_write(sc, n+1, APUREG_AMPLITUDE, 0xe800);
1269 		wp_apu_write(sc, n+1, APUREG_POSITION, 0x8f00
1270 		    | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT)
1271 		    | (PAN_LEFT << APU_PAN_SHIFT));
1272 		wp_apu_write(sc, n+1, APUREG_FREQ_LOBYTE, APU_plus6dB
1273 		    | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT));
1274 		wp_apu_write(sc, n+1, APUREG_FREQ_HIWORD, ch->dv >> 8);
1275 		if (ch->mode & MAESTRO_8BIT)
1276 			wp_apu_write(sc, n, APUREG_WAVESPACE,
1277 			    ch->wpwa & 0xff00);
1278 		    else
1279 			wp_apu_write(sc, n, APUREG_WAVESPACE,
1280 			    (ch->wpwa|(APU_STEREO >> 1)) & 0xff00);
1281 		wp_apu_write(sc, n, APUREG_CURPTR, ch->current);
1282 		wp_apu_write(sc, n, APUREG_ENDPTR, ch->end);
1283 		wp_apu_write(sc, n, APUREG_LOOPLEN, ch->end - ch->start);
1284 		wp_apu_write(sc, n, APUREG_AMPLITUDE, 0xe800);
1285 		wp_apu_write(sc, n, APUREG_POSITION, 0x8f00
1286 		    | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT)
1287 		    | (PAN_RIGHT << APU_PAN_SHIFT));
1288 		wp_apu_write(sc, n, APUREG_FREQ_LOBYTE, APU_plus6dB
1289 		    | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT));
1290 		wp_apu_write(sc, n, APUREG_FREQ_HIWORD, ch->dv >> 8);
1291 		wc_ctrl_write(sc, n, wcreg);
1292 		wc_ctrl_write(sc, n+1, wcreg);
1293 		wp_apu_write(sc, n, APUREG_APUTYPE,
1294 		    (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1295 		wp_apu_write(sc, n+1, APUREG_APUTYPE,
1296 		    (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1297 	}
1298 }
1299 
1300 int
1301 maestro_trigger_output(hdl, start, end, blksize, intr, arg, param)
1302 	void *hdl;
1303 	void *start, *end;
1304 	int blksize;
1305 	void (*intr)(void *);
1306 	void *arg;
1307 	struct audio_params *param;
1308 {
1309 	struct maestro_softc *sc = (struct maestro_softc *)hdl;
1310 
1311 	u_int offset = ((caddr_t)start - sc->dmabase) >> 1;
1312 	u_int size = ((char *)end - (char *)start) >> 1;
1313 	sc->play.mode |= MAESTRO_RUNNING;
1314 	sc->play.wpwa = APU_USE_SYSMEM | (offset >> 8);
1315 	DPRINTF(("maestro_trigger_output: start=%x, end=%x, blksize=%x ",
1316 		start, end, blksize));
1317     	DPRINTF(("offset = %x, size=%x\n", offset, size));
1318 
1319 	sc->play.intr = intr;
1320 	sc->play.intr_arg = arg;
1321 	sc->play.blocksize = blksize;
1322 	sc->play.end = offset+size;
1323 	sc->play.start = offset;
1324 	sc->play.current = sc->play.start;
1325 	if ((sc->play.mode & (MAESTRO_STEREO | MAESTRO_8BIT)) == MAESTRO_STEREO) {
1326 		sc->play.wpwa >>= 1;
1327 		sc->play.start >>= 1;
1328 		sc->play.end >>= 1;
1329 		sc->play.blocksize >>= 1;
1330 	}
1331 	maestro_channel_start(&sc->play);
1332 
1333 	sc->play.threshold = sc->play.start;
1334 	maestro_update_timer(sc);
1335 
1336 	return 0;
1337 }
1338 
1339 /* -----------------------------
1340  * Codec interface
1341  */
1342 
1343 enum ac97_host_flags
1344 maestro_codec_flags(self)
1345 	void *self;
1346 {
1347 	return AC97_HOST_DONT_READ;
1348 }
1349 
1350 int
1351 maestro_read_codec(self, regno, datap)
1352 	void *self;
1353 	u_int8_t regno;
1354 	u_int16_t *datap;
1355 {
1356 	struct maestro_softc *sc = (struct maestro_softc *)self;
1357 	int t;
1358 
1359 	/* We have to wait for a SAFE time to write addr/data */
1360 	for (t = 0; t < 20; t++) {
1361 		if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT)
1362 		    & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS)
1363 			break;
1364 		DELAY(2);	/* 20.8us / 13 */
1365 	}
1366 	if (t == 20)
1367 		printf("%s: maestro_read_codec() PROGLESS timed out.\n",
1368 		    sc->dev.dv_xname);
1369 		/* XXX return 1 */
1370 
1371 	bus_space_write_1(sc->iot, sc->ioh, PORT_CODEC_CMD,
1372 	    CODEC_CMD_READ | regno);
1373 	DELAY(21);	/* AC97 cycle = 20.8usec */
1374 
1375 	/* Wait for data retrieve */
1376 	for (t = 0; t < 20; t++) {
1377 		if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT)
1378 		    & CODEC_STAT_MASK) == CODEC_STAT_RW_DONE)
1379 			break;
1380 		DELAY(2);	/* 20.8us / 13 */
1381 	}
1382 	if (t == 20)
1383 		/* Timed out, but perform dummy read. */
1384 		printf("%s: maestro_read_codec() RW_DONE timed out.\n",
1385 		    sc->dev.dv_xname);
1386 
1387 	*datap = bus_space_read_2(sc->iot, sc->ioh, PORT_CODEC_REG);
1388 	return 0;
1389 }
1390 
1391 int
1392 maestro_write_codec(self, regno, data)
1393 	void *self;
1394 	u_int8_t regno;
1395 	u_int16_t data;
1396 {
1397 	struct maestro_softc *sc = (struct maestro_softc *)self;
1398 	int t;
1399 
1400 	/* We have to wait for a SAFE time to write addr/data */
1401 	for (t = 0; t < 20; t++) {
1402 		if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT)
1403 		    & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS)
1404 			break;
1405 		DELAY(2);	/* 20.8us / 13 */
1406 	}
1407 	if (t == 20) {
1408 		/* Timed out. Abort writing. */
1409 		printf("%s: maestro_write_codec() PROGLESS timed out.\n",
1410 		    sc->dev.dv_xname);
1411 		return 1;
1412 	}
1413 
1414 	bus_space_write_2(sc->iot, sc->ioh, PORT_CODEC_REG, data);
1415 	bus_space_write_1(sc->iot, sc->ioh, PORT_CODEC_CMD,
1416 	    CODEC_CMD_WRITE | regno);
1417 
1418 	return 0;
1419 }
1420 
1421 int
1422 maestro_attach_codec(self, cif)
1423 	void *self;
1424 	struct ac97_codec_if *cif;
1425 {
1426 	struct maestro_softc *sc = (struct maestro_softc *)self;
1427 
1428 	sc->codec_if = cif;
1429 	return 0;
1430 }
1431 
1432 void
1433 maestro_reset_codec(self)
1434 	void *self UNUSED;
1435 {
1436 }
1437 
1438 void
1439 maestro_initcodec(self)
1440 	void *self;
1441 {
1442 	struct maestro_softc *sc = (struct maestro_softc *)self;
1443 	u_int16_t data;
1444 
1445 	if (bus_space_read_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL)
1446 	    & RINGBUS_CTRL_ACLINK_ENABLED) {
1447 		bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 0);
1448 		DELAY(104);	/* 20.8us * (4 + 1) */
1449 	}
1450 	/* XXX - 2nd codec should be looked at. */
1451 	bus_space_write_4(sc->iot, sc->ioh,
1452 	    PORT_RINGBUS_CTRL, RINGBUS_CTRL_AC97_SWRESET);
1453 	DELAY(2);
1454 	bus_space_write_4(sc->iot, sc->ioh,
1455 	    PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED);
1456 	DELAY(21);
1457 
1458 	maestro_read_codec(sc, 0, &data);
1459 	if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT)
1460 	    & CODEC_STAT_MASK) != 0) {
1461 		bus_space_write_4(sc->iot, sc->ioh,
1462 		    PORT_RINGBUS_CTRL, 0);
1463 		DELAY(21);
1464 
1465 		/* Try cold reset. */
1466 		printf("%s: resetting codec\n", sc->dev.dv_xname);
1467 
1468 		data = bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DIR);
1469 		if (pci_conf_read(sc->pc, sc->pt, 0x58) & 1)
1470 			data |= 0x10;
1471 		data |= 0x009 &
1472 		    ~bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DATA);
1473 		bus_space_write_2(sc->iot, sc->ioh,
1474 		    PORT_GPIO_MASK, 0xff6);
1475 		bus_space_write_2(sc->iot, sc->ioh,
1476 		    PORT_GPIO_DIR, data | 0x009);
1477 		bus_space_write_2(sc->iot, sc->ioh,
1478 		    PORT_GPIO_DATA, 0x000);
1479 		DELAY(2);
1480 		bus_space_write_2(sc->iot, sc->ioh,
1481 		    PORT_GPIO_DATA, 0x001);
1482 		DELAY(1);
1483 		bus_space_write_2(sc->iot, sc->ioh,
1484 		    PORT_GPIO_DATA, 0x009);
1485 		DELAY(500000);
1486 		bus_space_write_2(sc->iot, sc->ioh,
1487 		    PORT_GPIO_DIR, data);
1488 		DELAY(84);	/* 20.8us * 4 */
1489 		bus_space_write_4(sc->iot, sc->ioh,
1490 		    PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED);
1491 		DELAY(21);
1492 	}
1493 
1494 	/* Check the codec to see is still busy */
1495 	if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) &
1496 	    CODEC_STAT_MASK) != 0) {
1497 		printf("%s: codec failure\n", sc->dev.dv_xname);
1498 	}
1499 }
1500 
1501 /* -----------------------------
1502  * Power management interface
1503  */
1504 
1505 void
1506 maestro_powerhook(why, self)
1507 	int why;
1508 	void *self;
1509 {
1510 	struct maestro_softc *sc = (struct maestro_softc *)self;
1511 
1512 	if (why != PWR_RESUME) {
1513 		/* Power down device on shutdown. */
1514 		DPRINTF(("maestro: power down\n"));
1515 		sc->suspend = why;
1516 		if (sc->record.mode & MAESTRO_RUNNING) {
1517 		    	sc->record.current = wp_apu_read(sc, sc->record.num, APUREG_CURPTR);
1518 			maestro_channel_stop(&sc->record);
1519 		}
1520 		if (sc->play.mode & MAESTRO_RUNNING) {
1521 		    	sc->play.current = wp_apu_read(sc, sc->play.num, APUREG_CURPTR);
1522 			maestro_channel_stop(&sc->play);
1523 		}
1524 
1525 		wp_stoptimer(sc);
1526 
1527 		/* Power down everything except clock. */
1528 		bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 0);
1529 		maestro_write_codec(sc, AC97_REG_POWER, 0xdf00);
1530 		DELAY(20);
1531 		bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 0);
1532 		DELAY(1);
1533 		maestro_power(sc, PPMI_D3);
1534 	} else {
1535 		/* Power up device on resume. */
1536 		DPRINTF(("maestro: power resume\n"));
1537 		if (sc->suspend == PWR_RESUME) {
1538 			printf("%s: resume without suspend?\n",
1539 			    sc->dev.dv_xname);
1540 			sc->suspend = why;
1541 			return;
1542 		}
1543 		sc->suspend = why;
1544 		maestro_power(sc, PPMI_D0);
1545 		DELAY(100000);
1546 		maestro_init(sc);
1547 		/* Restore codec settings */
1548 		if (sc->codec_if)
1549 			sc->codec_if->vtbl->restore_ports(sc->codec_if);
1550 		if (sc->play.mode & MAESTRO_RUNNING)
1551 			maestro_channel_start(&sc->play);
1552 		if (sc->record.mode & MAESTRO_RUNNING)
1553 			maestro_channel_start(&sc->record);
1554 		maestro_update_timer(sc);
1555 	}
1556 }
1557 
1558 void
1559 maestro_power(sc, status)
1560 	struct maestro_softc *sc;
1561 	int status;
1562 {
1563 	int data;
1564 
1565 	/* Set the power state of the device. */
1566 	data = pci_conf_read(sc->pc, sc->pt, CONF_PM_PTR);
1567 	data = pci_conf_read(sc->pc, sc->pt, data);
1568 	if (data == PPMI_CID)
1569 		pci_conf_write(sc->pc, sc->pt, data + PM_CTRL, status);
1570 }
1571 
1572 void
1573 maestro_channel_advance_dma(ch)
1574 	struct maestro_channel *ch;
1575 {
1576 	wpreg_t pos;
1577 #ifdef AUDIO_DEBUG
1578 	maestrointr_called++;
1579 #endif
1580 	for (;;) {
1581 		pos = wp_apu_read(ch->sc, ch->num, APUREG_CURPTR);
1582 		/* Are we still processing the current dma block ? */
1583 		if (pos >= ch->threshold &&
1584 		    pos < ch->threshold + ch->blocksize/2)
1585 			break;
1586 		ch->threshold += ch->blocksize/2;
1587 		if (ch->threshold >= ch->end)
1588 			ch->threshold = ch->start;
1589 		(*ch->intr)(ch->intr_arg);
1590 #ifdef AUDIO_DEBUG
1591 		maestrodma_effective++;
1592 #endif
1593 	}
1594 
1595 #ifdef AUDIO_DEBUG
1596 	if (maestrodebug && maestrointr_called % 64 == 0)
1597 		printf("maestro: dma advanced %lu for %lu calls\n",
1598 			maestrodma_effective, maestrointr_called);
1599 #endif
1600 }
1601 
1602 /* Some maestro makes sometimes get desynchronized in stereo mode. */
1603 void
1604 maestro_channel_suppress_jitter(ch)
1605 	struct maestro_channel *ch;
1606 {
1607 	int cp, diff;
1608 
1609 	/* Verify that both channels are not too far off. */
1610 	cp = wp_apu_read(ch->sc, ch->num, APUREG_CURPTR);
1611 	diff = wp_apu_read(ch->sc, ch->num+1, APUREG_CURPTR) - cp;
1612 	if (diff > 4 || diff < -4)
1613 		/* Otherwise, directly resynch the 2nd channel. */
1614 		bus_space_write_2(ch->sc->iot, ch->sc->ioh,
1615 		    PORT_DSP_DATA, cp);
1616 }
1617 
1618 /* -----------------------------
1619  * Interrupt handler interface
1620  */
1621 int
1622 maestro_intr(arg)
1623 	void *arg;
1624 {
1625 	struct maestro_softc *sc = (struct maestro_softc *)arg;
1626 	u_int16_t status;
1627 
1628 	status = bus_space_read_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT);
1629 	if (status == 0)
1630 		return 0;	/* Not for us? */
1631 
1632 	/* Acknowledge all. */
1633 	bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1);
1634 	bus_space_write_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT, status);
1635 
1636 	/* Hardware volume support */
1637 	if (status & HOSTINT_STAT_HWVOL && sc->codec_if != NULL) {
1638 		int n, i, delta, v;
1639 		mixer_ctrl_t hwvol;
1640 
1641 		n = bus_space_read_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER);
1642 		/* Special case: Mute key */
1643 		if (n & 0x11) {
1644 			hwvol.type = AUDIO_MIXER_ENUM;
1645 			hwvol.dev =
1646 			    sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if,
1647 				AudioCoutputs, AudioNmaster, AudioNmute);
1648 			sc->codec_if->vtbl->mixer_get_port(sc->codec_if, &hwvol);
1649 			hwvol.un.ord = !hwvol.un.ord;
1650 		} else {
1651 			hwvol.type = AUDIO_MIXER_VALUE;
1652 			hwvol.un.value.num_channels = 2;
1653 			hwvol.dev =
1654 			    sc->codec_if->vtbl->get_portnum_by_name(
1655 			    	sc->codec_if, AudioCoutputs, AudioNmaster,
1656 				    NULL);
1657 			sc->codec_if->vtbl->mixer_get_port(sc->codec_if, &hwvol);
1658 			/* XXX AC'97 yields five bits for master volume. */
1659 			delta = (n - MIDDLE_VOLUME)/STEP_VOLUME * 8;
1660 			for (i = 0; i < hwvol.un.value.num_channels; i++) {
1661 				v = ((int)hwvol.un.value.level[i]) + delta;
1662 				if (v < 0)
1663 					v = 0;
1664 				else if (v > 255)
1665 					v = 255;
1666 				hwvol.un.value.level[i] = v;
1667 			}
1668 		}
1669 		sc->codec_if->vtbl->mixer_set_port(sc->codec_if, &hwvol);
1670 		/* Reset to compute next diffs */
1671 		bus_space_write_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER,
1672 		    MIDDLE_VOLUME);
1673 	}
1674 
1675 	if (sc->play.mode & MAESTRO_RUNNING) {
1676 		maestro_channel_advance_dma(&sc->play);
1677 		if (sc->play.mode & MAESTRO_STEREO)
1678 			maestro_channel_suppress_jitter(&sc->play);
1679 	}
1680 
1681 	if (sc->record.mode & MAESTRO_RUNNING)
1682 		maestro_channel_advance_dma(&sc->record);
1683 
1684 	return 1;
1685 }
1686 
1687 /* -----------------------------
1688  * Hardware interface
1689  */
1690 
1691 /* Codec/Ringbus */
1692 
1693 void
1694 ringbus_setdest(struct maestro_softc *sc, int src, int dest)
1695 {
1696 	u_int32_t	data;
1697 
1698 	data = bus_space_read_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL);
1699 	data &= ~(0xfU << src);
1700 	data |= (0xfU & dest) << src;
1701 	bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, data);
1702 }
1703 
1704 /* Wave Processor */
1705 
1706 wpreg_t
1707 wp_reg_read(struct maestro_softc *sc, int reg)
1708 {
1709 	bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_INDEX, reg);
1710 	return bus_space_read_2(sc->iot, sc->ioh, PORT_DSP_DATA);
1711 }
1712 
1713 void
1714 wp_reg_write(struct maestro_softc *sc, int reg, wpreg_t data)
1715 {
1716 	bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_INDEX, reg);
1717 	bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, data);
1718 }
1719 
1720 static void
1721 apu_setindex(struct maestro_softc *sc, int reg)
1722 {
1723 	int t;
1724 
1725 	wp_reg_write(sc, WPREG_CRAM_PTR, reg);
1726 	/* Sometimes WP fails to set apu register index. */
1727 	for (t = 0; t < 1000; t++) {
1728 		if (bus_space_read_2(sc->iot, sc->ioh,
1729 		    PORT_DSP_DATA) == reg)
1730 			break;
1731 		bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, reg);
1732 	}
1733 	if (t == 1000)
1734 		printf("%s: apu_setindex() timeout\n", sc->dev.dv_xname);
1735 }
1736 
1737 wpreg_t
1738 wp_apu_read(struct maestro_softc *sc, int ch, int reg)
1739 {
1740 	wpreg_t ret;
1741 
1742 	apu_setindex(sc, ((unsigned)ch << 4) + reg);
1743 	ret = wp_reg_read(sc, WPREG_DATA_PORT);
1744 	return ret;
1745 }
1746 
1747 void
1748 wp_apu_write(struct maestro_softc *sc, int ch, int reg, wpreg_t data)
1749 {
1750 	int t;
1751 
1752 	apu_setindex(sc, ((unsigned)ch << 4) + reg);
1753 	wp_reg_write(sc, WPREG_DATA_PORT, data);
1754 	for (t = 0; t < 1000; t++) {
1755 		if (bus_space_read_2(sc->iot, sc->ioh, PORT_DSP_DATA) == data)
1756 			break;
1757 		bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, data);
1758 	}
1759 	if (t == 1000)
1760 		printf("%s: wp_apu_write() timeout\n", sc->dev.dv_xname);
1761 }
1762 
1763 void
1764 wp_settimer(struct maestro_softc *sc, u_int freq)
1765 {
1766 	u_int clock = 48000 << 2;
1767 	u_int prescale = 0, divide = (freq != 0) ? (clock / freq) : ~0;
1768 
1769 	if (divide < 4)
1770 		divide = 4;
1771 	else if (divide > 32 << 8)
1772 		divide = 32 << 8;
1773 
1774 	for (; divide > 32 << 1; divide >>= 1)
1775 		prescale++;
1776 	divide = (divide + 1) >> 1;
1777 
1778 	for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1)
1779 		prescale++;
1780 
1781 	wp_reg_write(sc, WPREG_TIMER_ENABLE, 0);
1782 	wp_reg_write(sc, WPREG_TIMER_FREQ,
1783 	    (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1));
1784 	wp_reg_write(sc, WPREG_TIMER_ENABLE, 1);
1785 }
1786 
1787 void
1788 wp_starttimer(struct maestro_softc *sc)
1789 {
1790 	wp_reg_write(sc, WPREG_TIMER_START, 1);
1791 }
1792 
1793 void
1794 wp_stoptimer(struct maestro_softc *sc)
1795 {
1796 	wp_reg_write(sc, WPREG_TIMER_START, 0);
1797 	bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1);
1798 }
1799 
1800 /* WaveCache */
1801 
1802 wcreg_t
1803 wc_reg_read(struct maestro_softc *sc, int reg)
1804 {
1805 	bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_INDEX, reg);
1806 	return bus_space_read_2(sc->iot, sc->ioh, PORT_WAVCACHE_DATA);
1807 }
1808 
1809 void
1810 wc_reg_write(struct maestro_softc *sc, int reg, wcreg_t data)
1811 {
1812 	bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_INDEX, reg);
1813 	bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_DATA, data);
1814 }
1815 
1816 u_int16_t
1817 wc_ctrl_read(struct maestro_softc *sc, int ch)
1818 {
1819 	return wc_reg_read(sc, ch << 3);
1820 }
1821 
1822 void
1823 wc_ctrl_write(struct maestro_softc *sc, int ch, wcreg_t data)
1824 {
1825 	wc_reg_write(sc, ch << 3, data);
1826 }
1827 
1828 /* -----------------------------
1829  * Simple zone allocator.
1830  * (All memory allocated in advance)
1831  */
1832 
1833 salloc_t
1834 salloc_new(addr, size, nzones)
1835 	caddr_t addr;
1836 	size_t size;
1837 	int nzones;
1838 {
1839 	struct salloc_pool *pool;
1840 	struct salloc_zone *space;
1841 	int i;
1842 
1843 	pool = malloc(sizeof *pool + nzones * sizeof pool->zones[0],
1844 	    M_TEMP, M_NOWAIT);
1845 	if (pool == NULL)
1846 		return NULL;
1847 	SLIST_INIT(&pool->free);
1848 	SLIST_INIT(&pool->used);
1849 	SLIST_INIT(&pool->spare);
1850 	/* Espie says the following line is obvious */
1851 	pool->zones = (struct salloc_zone *)(pool + 1);
1852 	for (i = 1; i < nzones; i++)
1853 		SLIST_INSERT_HEAD(&pool->spare, &pool->zones[i], link);
1854 	space = &pool->zones[0];
1855 	space->addr = addr;
1856 	space->size = size;
1857 	SLIST_INSERT_HEAD(&pool->free, space, link);
1858 	return pool;
1859 }
1860 
1861 void
1862 salloc_destroy(pool)
1863 	salloc_t pool;
1864 {
1865 	free(pool, M_TEMP);
1866 }
1867 
1868 void
1869 salloc_insert(pool, head, zone, merge)
1870 	salloc_t pool;
1871 	struct salloc_head *head;
1872 	struct salloc_zone *zone;
1873 	int merge;
1874 {
1875 	struct salloc_zone *prev, *next;
1876 
1877 	/*
1878 	 * Insert a zone into an ordered list of zones, possibly
1879 	 * merging adjacent zones.
1880 	 */
1881 	prev = NULL;
1882 	SLIST_FOREACH(next, head, link) {
1883 		if (next->addr > zone->addr)
1884 			break;
1885 		prev = next;
1886 	}
1887 
1888 	if (merge && prev && prev->addr + prev->size == zone->addr) {
1889 		prev->size += zone->size;
1890 		SLIST_INSERT_HEAD(&pool->spare, zone, link);
1891 		zone = prev;
1892 	} else if (prev)
1893 		SLIST_INSERT_AFTER(prev, zone, link);
1894 	else
1895 		SLIST_INSERT_HEAD(head, zone, link);
1896 	if (merge && next && zone->addr + zone->size == next->addr) {
1897 		zone->size += next->size;
1898 		SLIST_REMOVE(head, next, salloc_zone, link);
1899 		SLIST_INSERT_HEAD(&pool->spare, next, link);
1900 	}
1901 }
1902 
1903 caddr_t
1904 salloc_alloc(pool, size)
1905 	salloc_t pool;
1906 	size_t size;
1907 {
1908 	struct salloc_zone *zone, *uzone;
1909 
1910 	SLIST_FOREACH(zone, &pool->free, link)
1911 		if (zone->size >= size)
1912 			break;
1913 	if (zone == SLIST_END(&pool->free))
1914 		return NULL;
1915 	if (zone->size == size) {
1916 		SLIST_REMOVE(&pool->free, zone, salloc_zone, link);
1917 		uzone = zone;
1918 	} else {
1919 		uzone = SLIST_FIRST(&pool->spare);
1920 		if (uzone == NULL)
1921 			return NULL;		/* XXX */
1922 		SLIST_REMOVE_HEAD(&pool->spare, link);
1923 		uzone->size = size;
1924 		uzone->addr = zone->addr;
1925 		zone->size -= size;
1926 		zone->addr += size;
1927 	}
1928 	salloc_insert(pool, &pool->used, uzone, 0);
1929 	return uzone->addr;
1930 }
1931 
1932 void
1933 salloc_free(pool, addr)
1934 	salloc_t pool;
1935 	caddr_t addr;
1936 {
1937 	struct salloc_zone *zone;
1938 
1939 	SLIST_FOREACH(zone, &pool->used, link)
1940 		if (zone->addr == addr)
1941 			break;
1942 #ifdef DIAGNOSTIC
1943 	if (zone == SLIST_END(&pool->used))
1944 		panic("salloc_free: freeing unallocated memory");
1945 #endif
1946 	SLIST_REMOVE(&pool->used, zone, salloc_zone, link);
1947 	salloc_insert(pool, &pool->free, zone, 1);
1948 }
1949