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