esa.c revision 1.3
1/* $NetBSD: esa.c,v 1.3 2002/01/07 07:33:09 jmcneill Exp $ */
2
3/*
4 * Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill@invisible.yi.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 *    derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28/*
29 * ESS Allegro-1 / Maestro3 Audio Driver
30 *
31 * Based on the FreeBSD maestro3 driver and the NetBSD eap driver.
32 * Original driver by Don Kim.
33 */
34
35#include <sys/types.h>
36#include <sys/errno.h>
37#include <sys/null.h>
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/malloc.h>
41#include <sys/device.h>
42#include <sys/conf.h>
43#include <sys/exec.h>
44#include <sys/select.h>
45#include <sys/audioio.h>
46
47#include <machine/bus.h>
48#include <machine/intr.h>
49
50#include <dev/pci/pcidevs.h>
51#include <dev/pci/pcivar.h>
52
53#include <dev/audio_if.h>
54#include <dev/mulaw.h>
55#include <dev/auconv.h>
56#include <dev/ic/ac97var.h>
57#include <dev/ic/ac97reg.h>
58
59
60#include <dev/pci/esareg.h>
61#include <dev/pci/esadsp.h>
62#include <dev/pci/esavar.h>
63
64#define PCI_CBIO	0x10
65
66#define ESA_DAC_DATA	0x1100
67
68enum {
69	ESS_ALLEGRO1,
70	ESS_MAESTRO3
71};
72
73static struct esa_card_type {
74	u_int16_t pci_vendor_id;
75	u_int16_t pci_product_id;
76	int type;
77	int delay1, delay2;
78} esa_card_types[] = {
79	{ PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_ALLEGRO1,
80	  ESS_ALLEGRO1, 50, 800 },
81	{ PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3,
82	  ESS_MAESTRO3, 20, 500 },
83	{ PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3_2,
84	  ESS_MAESTRO3, 20, 500 },
85	{ 0, 0, 0, 0, 0 }
86};
87
88struct audio_device esa_device = {
89	"ESS Allegro",
90	"",
91	"esa"
92};
93
94int		esa_match(struct device *, struct cfdata *, void *);
95void		esa_attach(struct device *, struct device *, void *);
96int		esa_detach(struct device *, int);
97
98/* audio(9) functions */
99int		esa_open(void *, int);
100void		esa_close(void *);
101int		esa_query_encoding(void *, struct audio_encoding *);
102int		esa_set_params(void *, int, int, struct audio_params *,
103			       struct audio_params *);
104int		esa_round_blocksize(void *, int);
105int		esa_init_output(void *, void *, int);
106int		esa_halt_output(void *);
107int		esa_halt_input(void *);
108int		esa_set_port(void *, mixer_ctrl_t *);
109int		esa_get_port(void *, mixer_ctrl_t *);
110int		esa_query_devinfo(void *, mixer_devinfo_t *);
111void *		esa_malloc(void *, int, size_t, int, int);
112void		esa_free(void *, void *, int);
113int		esa_getdev(void *, struct audio_device *);
114size_t		esa_round_buffersize(void *, int, size_t);
115int		esa_get_props(void *);
116int		esa_trigger_output(void *, void *, void *, int,
117				   void (*)(void *), void *,
118				   struct audio_params *);
119int		esa_trigger_input(void *, void *, void *, int,
120				  void (*)(void *), void *,
121				  struct audio_params *);
122
123int		esa_intr(void *);
124int		esa_allocmem(struct esa_softc *, size_t, size_t,
125			     struct esa_dma *);
126int		esa_freemem(struct esa_softc *, struct esa_dma *);
127paddr_t		esa_mappage(void *addr, void *mem, off_t off, int prot);
128
129/* Supporting subroutines */
130u_int16_t	esa_read_assp(struct esa_softc *, u_int16_t, u_int16_t);
131void		esa_write_assp(struct esa_softc *, u_int16_t, u_int16_t,
132			       u_int16_t);
133int		esa_init_codec(struct esa_softc *);
134int		esa_attach_codec(void *, struct ac97_codec_if *);
135int		esa_read_codec(void *, u_int8_t, u_int16_t *);
136int		esa_write_codec(void *, u_int8_t, u_int16_t);
137void		esa_reset_codec(void *);
138enum ac97_host_flags	esa_flags_codec(void *);
139int		esa_wait(struct esa_softc *);
140int		esa_init(struct esa_softc *);
141void		esa_config(struct esa_softc *);
142u_int8_t	esa_assp_halt(struct esa_softc *);
143void		esa_codec_reset(struct esa_softc *);
144int		esa_amp_enable(struct esa_softc *);
145void		esa_enable_interrupts(struct esa_softc *);
146int		esa_power(struct esa_softc *, int);
147u_int32_t	esa_get_pointer(struct esa_softc *, struct esa_channel *);
148
149struct device *	audio_attach_mi_lkm(struct audio_hw_if *, void *,
150				    struct device *);
151
152static audio_encoding_t esa_encoding[] = {
153	{ 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 },
154	{ 1, AudioEmulaw, AUDIO_ENCODING_ULAW, 8,
155		AUDIO_ENCODINGFLAG_EMULATED },
156	{ 2, AudioEalaw, AUDIO_ENCODING_ALAW, 8, AUDIO_ENCODINGFLAG_EMULATED },
157	{ 3, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8,
158		AUDIO_ENCODINGFLAG_EMULATED }, /* XXX: Are you sure? */
159	{ 4, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 },
160	{ 5, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16,
161		AUDIO_ENCODINGFLAG_EMULATED },
162	{ 6, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16,
163		AUDIO_ENCODINGFLAG_EMULATED },
164	{ 7, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16,
165		AUDIO_ENCODINGFLAG_EMULATED }
166};
167
168#define ESA_NENCODINGS 8
169
170struct audio_hw_if esa_hw_if = {
171	esa_open,
172	esa_close,
173	NULL,			/* drain */
174	esa_query_encoding,
175	esa_set_params,
176	esa_round_blocksize,
177	NULL,			/* commit_settings */
178	esa_init_output,
179	NULL,			/* esa_init_input */
180	NULL,			/* start_output */
181	NULL,			/* start_input */
182	esa_halt_output,
183	esa_halt_input,
184	NULL,			/* speaker_ctl */
185	esa_getdev,
186	NULL,			/* getfd */
187	esa_set_port,
188	esa_get_port,
189	esa_query_devinfo,
190	esa_malloc,
191	esa_free,
192	esa_round_buffersize,
193	esa_mappage,
194	esa_get_props,
195	esa_trigger_output,
196	esa_trigger_input
197};
198
199struct cfattach esa_ca = {
200	sizeof(struct esa_softc), esa_match, esa_attach,
201	esa_detach, /*esa_activate*/ NULL
202};
203
204/*
205 * audio(9) functions
206 */
207
208int
209esa_open(void *hdl, int flags)
210{
211
212	return (0);
213}
214
215void
216esa_close(void *hdl)
217{
218
219	return;
220}
221
222int
223esa_query_encoding(void *hdl, struct audio_encoding *ae)
224{
225
226	if (ae->index < 0 || ae->index >= ESA_NENCODINGS)
227		return (EINVAL);
228	*ae = esa_encoding[ae->index];
229
230	return (0);
231}
232
233int
234esa_set_params(void *hdl, int setmode, int usemode, struct audio_params *play,
235	       struct audio_params *rec)
236{
237	struct esa_softc *sc = hdl;
238	struct esa_channel *ch;
239	struct audio_params *p;
240	u_int32_t data;
241	u_int32_t freq;
242	int mode;
243
244	for (mode = AUMODE_RECORD; mode != -1;
245	     mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
246		if ((setmode & mode) == 0)
247			continue;
248
249		switch (mode) {
250		case AUMODE_PLAY:
251			p = play;
252			ch = &sc->play;
253			break;
254		case AUMODE_RECORD:
255			p = rec;
256			ch = &sc->rec;
257			break;
258		}
259
260		if (p->sample_rate < ESA_MINRATE ||
261		    p->sample_rate > ESA_MAXRATE ||
262		    (p->precision != 8 && p->precision != 16) ||
263		    (p->channels < 1 && p->channels > 2))
264			return (EINVAL);
265
266		p->factor = 1;
267		p->sw_code = 0;
268
269		switch(p->encoding) {
270		case AUDIO_ENCODING_SLINEAR_BE:
271			if (p->precision == 16)
272				p->sw_code = swap_bytes;
273			else
274				p->sw_code = change_sign8;
275			break;
276		case AUDIO_ENCODING_SLINEAR_LE:
277			if (p->precision != 16)
278				p->sw_code = change_sign8;
279			break;
280		case AUDIO_ENCODING_ULINEAR_BE:
281			if (p->precision == 16) {
282				if (mode == AUMODE_PLAY)
283					p->sw_code =
284					    swap_bytes_change_sign16_le;
285				else
286					p->sw_code =
287					    change_sign16_swap_bytes_le;
288			}
289			break;
290		case AUDIO_ENCODING_ULINEAR_LE:
291			if (p->precision == 16)
292				p->sw_code = change_sign16_le;
293			break;
294		case AUDIO_ENCODING_ULAW:
295			if (mode == AUMODE_PLAY) {
296				p->factor = 2;
297				p->sw_code = mulaw_to_slinear16_le;
298			} else
299				p->sw_code = ulinear8_to_mulaw;
300			break;
301		case AUDIO_ENCODING_ALAW:
302			if (mode == AUMODE_PLAY) {
303				p->factor = 2;
304				p->sw_code = alaw_to_slinear16_le;
305			} else
306				p->sw_code = ulinear8_to_alaw;
307			break;
308		default:
309			return (EINVAL);
310		}
311
312		if (p->channels == 1)
313			data = 1;
314		else
315			data = 0;
316		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
317			       ch->data_offset + ESA_SRC3_MODE_OFFSET,
318		    data);
319
320		if (play->precision * play->factor == 8)
321			data = 1;
322		else
323			data = 0;
324		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
325			       ch->data_offset + ESA_SRC3_WORD_LENGTH_OFFSET,
326			       data);
327
328		if ((freq = ((p->sample_rate << 15) + 24000) / 48000) != 0) {
329			freq--;
330		}
331		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
332			       ch->data_offset + ESA_CDATA_FREQUENCY, freq);
333	}
334
335	return (0);
336}
337
338int
339esa_round_blocksize(void *hdl, int bs)
340{
341	struct esa_softc *sc = hdl;
342
343	sc->play.blksize = sc->rec.blksize = 4096;
344
345	return (sc->play.blksize);
346}
347
348int
349esa_init_output(void *hdl, void *buffer, int size)
350{
351
352	return (0);
353}
354
355int
356esa_halt_output(void *hdl)
357{
358	struct esa_softc *sc = hdl;
359
360	if (sc->play.active == 0)
361		return (0);
362
363	sc->play.active = 0;
364
365	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
366		       ESA_KDATA_INSTANCE0_MINISRC, 0);
367	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_XFER0, 0);
368	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_MIXER_XFER0, 0);
369
370	return (0);
371}
372
373int
374esa_halt_input(void *hdl)
375{
376	struct esa_softc *sc = hdl;
377	bus_space_tag_t iot = sc->sc_iot;
378	bus_space_handle_t ioh = sc->sc_ioh;
379	u_int32_t data;
380
381	if (sc->rec.active == 0)
382		return (0);
383
384	sc->rec.active = 0;
385
386	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
387		       ESA_KDATA_TIMER_COUNT_RELOAD, 0);
388	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_TIMER_COUNT_CURRENT, 0);
389	data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL);
390	bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, data & ~ESA_CLKRUN_GEN_ENABLE);
391
392	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, sc->rec.data_offset +
393		       ESA_CDATA_INSTANCE_READY, 0);
394	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_REQUEST, 0);
395
396	return (0);
397}
398
399void *
400esa_malloc(void *hdl, int direction, size_t size, int type, int flags)
401{
402	struct esa_softc *sc = hdl;
403	struct esa_dma *p;
404	int error;
405
406	p = malloc(sizeof(*p), type, flags);
407	if (!p)
408		return (0);
409	error = esa_allocmem(sc, size, 16, p);
410	if (error) {
411		free(p, type);
412		printf("%s: esa_malloc: not enough memory\n",
413		    sc->sc_dev.dv_xname);
414		return (0);
415	}
416	p->next = sc->sc_dmas;
417	sc->sc_dmas = p;
418
419	return (KERNADDR(p));
420}
421
422void
423esa_free(void *hdl, void *addr, int type)
424{
425	struct esa_softc *sc = hdl;
426	struct esa_dma *p;
427	struct esa_dma **pp;
428
429	for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next)
430		if (KERNADDR(p) == addr) {
431			esa_freemem(sc, p);
432			*pp = p->next;
433			free(p, type);
434			return;
435		}
436}
437
438int
439esa_getdev(void *hdl, struct audio_device *ret)
440{
441
442	*ret = esa_device;
443
444	return (0);
445}
446
447int
448esa_set_port(void *hdl, mixer_ctrl_t *mc)
449{
450	struct esa_softc *sc = hdl;
451
452	return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, mc));
453}
454
455int
456esa_get_port(void *hdl, mixer_ctrl_t *mc)
457{
458	struct esa_softc *sc = hdl;
459
460	return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, mc));
461}
462
463int
464esa_query_devinfo(void *hdl, mixer_devinfo_t *di)
465{
466	struct esa_softc *sc = hdl;
467
468	return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, di));
469}
470
471size_t
472esa_round_buffersize(void *hdl, int direction, size_t bufsize)
473{
474	struct esa_softc *sc = hdl;
475
476	sc->play.bufsize = sc->rec.bufsize = 65536;
477
478	return (sc->play.bufsize);
479}
480
481int
482esa_get_props(void *hdl)
483{
484
485	return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
486}
487
488int
489esa_trigger_output(void *hdl, void *start, void *end, int blksize,
490			void (*intr)(void *), void *intrarg,
491			struct audio_params *param)
492{
493	struct esa_softc *sc = hdl;
494	struct esa_dma *p;
495	bus_space_tag_t iot = sc->sc_iot;
496	bus_space_handle_t ioh = sc->sc_ioh;
497	u_int32_t data;
498	u_int32_t bufaddr;
499	u_int32_t i;
500	size_t size;
501	int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) +
502			   (ESA_MINISRC_IN_BUFFER_SIZE & ~1) +
503			   (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255)
504			   &~ 255;
505	int dac_data = ESA_DAC_DATA + data_bytes;
506	int dsp_in_size = ESA_MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
507	int dsp_out_size = ESA_MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
508	int dsp_in_buf = dac_data + (ESA_MINISRC_TMP_BUFFER_SIZE / 2);
509	int dsp_out_buf = dsp_in_buf + (dsp_in_size / 2) + 1;
510	sc->play.data_offset = dac_data;
511
512	if (sc->play.active)
513		return (EINVAL);
514
515	for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
516		;
517	if (!p) {
518		printf("%s: esa_trigger_output: bad addr %p\n",
519		    sc->sc_dev.dv_xname, start);
520		return (EINVAL);
521	}
522
523	sc->play.active = 1;
524	sc->play.intr = intr;
525	sc->play.arg = intrarg;
526	sc->play.pos = 0;
527	sc->play.count = 0;
528	sc->play.buf = start;
529	size = (size_t)(((caddr_t)end - (caddr_t)start));
530	bufaddr = DMAADDR(p);
531	sc->play.start = bufaddr;
532
533#define LO(x) ((x) & 0x0000ffff)
534#define HI(x) ((x) >> 16)
535
536	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
537	    ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr));
538	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
539	    ESA_CDATA_HOST_SRC_ADDRH, HI(bufaddr));
540	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
541	    ESA_CDATA_HOST_SRC_END_PLUS_1L, LO(bufaddr + size));
542	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
543	    ESA_CDATA_HOST_SRC_END_PLUS_1H, HI(bufaddr + size));
544	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
545	    ESA_CDATA_HOST_SRC_CURRENTL, LO(bufaddr));
546	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
547	    ESA_CDATA_HOST_SRC_CURRENTH, HI(bufaddr));
548
549	/* DSP buffers */
550	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
551	    ESA_CDATA_IN_BUF_BEGIN, dsp_in_buf);
552	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
553	    ESA_CDATA_IN_BUF_END_PLUS_1, dsp_in_buf + (dsp_in_size / 2));
554	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
555	    ESA_CDATA_IN_BUF_HEAD, dsp_in_buf);
556	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
557	    ESA_CDATA_IN_BUF_TAIL, dsp_in_buf);
558	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
559	    ESA_CDATA_OUT_BUF_BEGIN, dsp_out_buf);
560	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
561	    ESA_CDATA_OUT_BUF_END_PLUS_1, dsp_out_buf + (dsp_out_size / 2));
562	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
563	    ESA_CDATA_OUT_BUF_HEAD, dsp_out_buf);
564	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
565	    ESA_CDATA_OUT_BUF_TAIL, dsp_out_buf);
566
567	/* Some per-client initializers */
568	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
569	    ESA_SRC3_DIRECTION_OFFSET + 12, dac_data + 40 + 8);
570	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
571	    ESA_SRC3_DIRECTION_OFFSET + 19, 0x400 + ESA_MINISRC_COEF_LOC);
572	/* Enable or disable low-pass filter? (0xff if rate > 45000) */
573	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
574	    ESA_SRC3_DIRECTION_OFFSET + 22, 0);
575	/* Tell it which way DMA is going */
576	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
577	    ESA_CDATA_DMA_CONTROL,
578	    ESA_DMACONTROL_AUTOREPEAT + ESA_DMAC_PAGE3_SELECTOR +
579	    ESA_DMAC_BLOCKF_SELECTOR);
580
581	/* Set an armload of static initializers */
582	for (i = 0; i < (sizeof(esa_playvals) / sizeof(esa_playvals[0])); i++)
583		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
584		    esa_playvals[i].addr, esa_playvals[i].val);
585
586	/* Put us in the packed task lists */
587	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
588	    ESA_KDATA_INSTANCE0_MINISRC,
589	    dac_data >> ESA_DP_SHIFT_COUNT);
590	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_XFER0,
591	    dac_data >> ESA_DP_SHIFT_COUNT);
592	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_MIXER_XFER0,
593	    dac_data >> ESA_DP_SHIFT_COUNT);
594#undef LO
595#undef HI
596
597	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
598	    ESA_KDATA_TIMER_COUNT_RELOAD, 240);
599	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
600	    ESA_KDATA_TIMER_COUNT_CURRENT, 240);
601	data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL);
602	bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL,
603	    data | ESA_CLKRUN_GEN_ENABLE);
604
605	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
606	    ESA_CDATA_INSTANCE_READY, 1);
607	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
608	    ESA_KDATA_MIXER_TASK_NUMBER, 1);
609
610	return (0);
611}
612
613int
614esa_trigger_input(void *hdl, void *start, void *end, int blksize,
615			void (*intr)(void *), void *intrarg,
616			struct audio_params *param)
617{
618	struct esa_softc *sc = hdl;
619	struct esa_dma *p;
620	bus_space_tag_t iot = sc->sc_iot;
621	bus_space_handle_t ioh = sc->sc_ioh;
622	u_int32_t data;
623	u_int32_t bufaddr;
624	u_int32_t i;
625	size_t size;
626	int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) +
627			   (ESA_MINISRC_IN_BUFFER_SIZE & ~1) +
628			   (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255)
629			   &~ 255;
630	int adc_data = ESA_DAC_DATA + data_bytes + (data_bytes / 2);
631	int dsp_in_size = ESA_MINISRC_IN_BUFFER_SIZE - (0x10 * 2);
632	int dsp_out_size = ESA_MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
633	int dsp_in_buf = adc_data + (ESA_MINISRC_TMP_BUFFER_SIZE / 2);
634	int dsp_out_buf = dsp_in_buf + (dsp_in_size / 2) + 1;
635	sc->rec.data_offset = adc_data;
636
637	if (sc->rec.active)
638		return (EINVAL);
639
640	for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
641		;
642	if (!p) {
643		printf("%s: esa_trigger_input: bad addr %p\n",
644		    sc->sc_dev.dv_xname, start);
645		return (EINVAL);
646	}
647
648	sc->rec.active = 1;
649	sc->rec.intr = intr;
650	sc->rec.arg = intrarg;
651	sc->rec.pos = 0;
652	sc->rec.count = 0;
653	sc->rec.buf = start;
654	size = (size_t)(((caddr_t)end - (caddr_t)start));
655	bufaddr = DMAADDR(p);
656	sc->rec.start = bufaddr;
657
658#define LO(x) ((x) & 0x0000ffff)
659#define HI(x) ((x) >> 16)
660
661	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
662	    ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr));
663	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
664	    ESA_CDATA_HOST_SRC_ADDRH, HI(bufaddr));
665	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
666	    ESA_CDATA_HOST_SRC_END_PLUS_1L, LO(bufaddr + size));
667	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
668	    ESA_CDATA_HOST_SRC_END_PLUS_1H, HI(bufaddr + size));
669	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
670	    ESA_CDATA_HOST_SRC_CURRENTL, LO(bufaddr));
671	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
672	    ESA_CDATA_HOST_SRC_CURRENTH, HI(bufaddr));
673
674	/* DSP buffers */
675	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
676	    ESA_CDATA_IN_BUF_BEGIN, dsp_in_buf);
677	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
678	    ESA_CDATA_IN_BUF_END_PLUS_1, dsp_in_buf + (dsp_in_size / 2));
679	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
680	    ESA_CDATA_IN_BUF_HEAD, dsp_in_buf);
681	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
682	    ESA_CDATA_IN_BUF_TAIL, dsp_in_buf);
683	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
684	    ESA_CDATA_OUT_BUF_BEGIN, dsp_out_buf);
685	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
686	    ESA_CDATA_OUT_BUF_END_PLUS_1, dsp_out_buf + (dsp_out_size / 2));
687	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
688	    ESA_CDATA_OUT_BUF_HEAD, dsp_out_buf);
689	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
690	    ESA_CDATA_OUT_BUF_TAIL, dsp_out_buf);
691
692	/* Some per-client initializers */
693	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
694	    ESA_SRC3_DIRECTION_OFFSET + 12, adc_data + 40 + 8);
695	/* Tell it which way DMA is going */
696	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
697	    ESA_CDATA_DMA_CONTROL,
698	    ESA_DMACONTROL_DIRECTION + ESA_DMACONTROL_AUTOREPEAT +
699	    ESA_DMAC_PAGE3_SELECTOR + ESA_DMAC_BLOCKF_SELECTOR);
700
701	/* Set an armload of static initializers */
702	for (i = 0; i < (sizeof(esa_recvals) / sizeof(esa_recvals[0])); i++)
703		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
704		    esa_recvals[i].addr, esa_recvals[i].val);
705
706	/* Put us in the packed task lists */
707	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
708	    ESA_KDATA_INSTANCE0_MINISRC,
709	    adc_data >> ESA_DP_SHIFT_COUNT);
710	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_XFER0,
711	    adc_data >> ESA_DP_SHIFT_COUNT);
712	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_XFER0,
713	    adc_data >> ESA_DP_SHIFT_COUNT);
714#undef LO
715#undef HI
716
717	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
718	    ESA_KDATA_TIMER_COUNT_RELOAD, 240);
719	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
720	    ESA_KDATA_TIMER_COUNT_CURRENT, 240);
721	data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL);
722	bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL,
723	    data | ESA_CLKRUN_GEN_ENABLE);
724
725	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_REQUEST, 1);
726	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
727	    ESA_CDATA_INSTANCE_READY, 1);
728
729	return (0);
730}
731
732/* Interrupt handler */
733
734int
735esa_intr(void *hdl)
736{
737	struct esa_softc *sc = hdl;
738	bus_space_tag_t iot = sc->sc_iot;
739	bus_space_handle_t ioh = sc->sc_ioh;
740	u_int32_t status, ctl;
741	u_int32_t pos;
742	u_int32_t diff;
743	u_int32_t play_blksize = sc->play.blksize;
744	u_int32_t play_bufsize = sc->play.bufsize;
745	u_int32_t rec_blksize = sc->rec.blksize;
746	u_int32_t rec_bufsize = sc->rec.bufsize;
747
748	status = bus_space_read_1(iot, ioh, ESA_HOST_INT_STATUS);
749	if (!status)
750		return (0);
751
752	/* ack the interrupt */
753	bus_space_write_1(iot, ioh, ESA_HOST_INT_STATUS, 0xff);
754
755	if (status & ESA_HV_INT_PENDING) {
756		u_int8_t event;
757
758		printf("%s: hardware volume interrupt\n", sc->sc_dev.dv_xname);
759		event = bus_space_read_1(iot, ioh, ESA_HW_VOL_COUNTER_MASTER);
760		switch(event) {
761		case 0x99:
762		case 0xaa:
763		case 0x66:
764		case 0x88:
765			printf("%s: esa_intr: FIXME\n", sc->sc_dev.dv_xname);
766			break;
767		default:
768			printf("%s: unknown hwvol event 0x%02x\n",
769			    sc->sc_dev.dv_xname, event);
770			break;
771		}
772		bus_space_write_1(iot, ioh, ESA_HW_VOL_COUNTER_MASTER, 0x88);
773	}
774
775	if (status & ESA_ASSP_INT_PENDING) {
776		ctl = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_B);
777		if (!(ctl & ESA_STOP_ASSP_CLOCK)) {
778			ctl = bus_space_read_1(iot, ioh,
779					       ESA_ASSP_HOST_INT_STATUS);
780			if (ctl & ESA_DSP2HOST_REQ_TIMER) {
781				bus_space_write_1(iot, ioh,
782				    ESA_ASSP_HOST_INT_STATUS,
783				    ESA_DSP2HOST_REQ_TIMER);
784				if (sc->play.active) {
785					pos = esa_get_pointer(sc, &sc->play)
786					    % play_bufsize;
787					diff = (play_bufsize + pos - sc->play.pos)
788					    % play_bufsize;
789					sc->play.pos = pos;
790					sc->play.count += diff;
791					while(sc->play.count >= play_blksize) {
792						sc->play.count -= play_blksize;
793						(*sc->play.intr)(sc->play.arg);
794					}
795				}
796				if (sc->rec.active) {
797					pos = esa_get_pointer(sc, &sc->rec)
798					    % rec_bufsize;
799					diff = (rec_bufsize + pos - sc->rec.pos)
800					    % rec_bufsize;
801					sc->rec.pos = pos;
802					sc->rec.count += diff;
803					while(sc->rec.count >= rec_blksize) {
804						sc->rec.count -= rec_blksize;
805						(*sc->rec.intr)(sc->rec.arg);
806					}
807				}
808			}
809		}
810	}
811
812	return (1);
813}
814
815int
816esa_allocmem(struct esa_softc *sc, size_t size, size_t align,
817		struct esa_dma *p)
818{
819	int error;
820
821	p->size = size;
822	error = bus_dmamem_alloc(sc->sc_dmat, p->size, align, 0,
823				 p->segs, sizeof(p->segs) / sizeof(p->segs[0]),
824				 &p->nsegs, BUS_DMA_NOWAIT);
825	if (error)
826		return (error);
827
828	error = bus_dmamem_map(sc->sc_dmat, p->segs, p->nsegs, p->size,
829				&p->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
830	if (error)
831		goto free;
832
833	error = bus_dmamap_create(sc->sc_dmat, p->size, 1, p->size, 0,
834				  BUS_DMA_NOWAIT, &p->map);
835	if (error)
836		goto unmap;
837
838	error = bus_dmamap_load(sc->sc_dmat, p->map, p->addr, p->size, NULL,
839				BUS_DMA_NOWAIT);
840	if (error)
841		goto destroy;
842
843	return (0);
844
845destroy:
846	bus_dmamap_destroy(sc->sc_dmat, p->map);
847unmap:
848	bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size);
849free:
850	bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
851
852	return (error);
853}
854
855int
856esa_freemem(struct esa_softc *sc, struct esa_dma *p)
857{
858
859	bus_dmamap_unload(sc->sc_dmat, p->map);
860	bus_dmamap_destroy(sc->sc_dmat, p->map);
861	bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size);
862	bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
863
864	return (0);
865}
866
867/*
868 * Supporting Subroutines
869 */
870
871int
872esa_match(struct device *dev, struct cfdata *match, void *aux)
873{
874	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
875
876	switch(PCI_VENDOR(pa->pa_id)) {
877	case PCI_VENDOR_ESSTECH:
878		switch(PCI_PRODUCT(pa->pa_id)) {
879		case PCI_PRODUCT_ESSTECH_ALLEGRO1:
880		case PCI_PRODUCT_ESSTECH_MAESTRO3:
881		case PCI_PRODUCT_ESSTECH_MAESTRO3_2:
882			return (1);
883		}
884	}
885
886	return (0);
887}
888
889void
890esa_attach(struct device *parent, struct device *self, void *aux)
891{
892	struct esa_softc *sc = (struct esa_softc *)self;
893	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
894	pcitag_t tag = pa->pa_tag;
895	pci_chipset_tag_t pc = pa->pa_pc;
896	pci_intr_handle_t ih;
897	struct esa_card_type *card;
898	const char *intrstr;
899	u_int32_t data;
900	char devinfo[256];
901	int revision;
902
903	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
904	revision = PCI_REVISION(pa->pa_class);
905	printf(": %s (rev. 0x%02x)\n", devinfo, revision);
906
907	for (card = esa_card_types; card->pci_vendor_id; card++)
908		if (PCI_VENDOR(pa->pa_id) == card->pci_vendor_id &&
909		    PCI_PRODUCT(pa->pa_id) == card->pci_product_id) {
910			sc->type = card->type;
911			sc->delay1 = card->delay1;
912			sc->delay2 = card->delay2;
913			break;
914		}
915
916	data = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
917	data |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE
918	    | PCI_COMMAND_MASTER_ENABLE);
919	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, data);
920
921	/* Map I/O register */
922	if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
923	    &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios)) {
924		printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
925		return;
926	}
927
928	/* Initialize softc */
929	sc->sc_tag = tag;
930	sc->sc_pct = pc;
931	sc->sc_dmat = pa->pa_dmat;
932
933	/* Map and establish an interrupt */
934	if (pci_intr_map(pa, &ih)) {
935		printf("%s: can't map interrupt\n", sc->sc_dev.dv_xname);
936		return;
937	}
938	intrstr = pci_intr_string(pc, ih);
939	sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, esa_intr, self);
940	if (sc->sc_ih == NULL) {
941		printf("%s: can't establish interrupt", sc->sc_dev.dv_xname);
942		if (intrstr != NULL)
943			printf(" at %s", intrstr);
944		printf("\n");
945		return;
946	}
947	printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
948
949	/* Power up chip */
950	esa_power(sc, 0);
951
952	/* Init chip */
953	if (esa_init(sc) == -1) {
954		printf("%s: esa_attach: unable to initialize the card\n",
955		    sc->sc_dev.dv_xname);
956		return;
957	}
958
959	/* Attach AC97 host interface */
960	sc->host_if.arg = self;
961	sc->host_if.attach = esa_attach_codec;
962	sc->host_if.read = esa_read_codec;
963	sc->host_if.write = esa_write_codec;
964	sc->host_if.reset = esa_reset_codec;
965	sc->host_if.flags = esa_flags_codec;
966
967	if (ac97_attach(&sc->host_if) != 0)
968		return;
969
970	sc->sc_audiodev = audio_attach_mi(&esa_hw_if, self, &sc->sc_dev);
971
972	return;
973}
974
975int
976esa_detach(struct device *self, int flags)
977{
978	struct esa_softc *sc = (struct esa_softc *)self;
979	int rv = 0;
980
981	if (sc->sc_audiodev != NULL)
982		rv = config_detach(sc->sc_audiodev, flags);
983	if (rv)
984		return (rv);
985
986	if (sc->sc_ih != NULL)
987		pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
988	if (sc->sc_ios)
989		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
990
991	return (0);
992}
993
994u_int16_t
995esa_read_assp(struct esa_softc *sc, u_int16_t region, u_int16_t index)
996{
997	u_int16_t data;
998	bus_space_tag_t iot = sc->sc_iot;
999	bus_space_handle_t ioh = sc->sc_ioh;
1000
1001	bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_TYPE,
1002	    region & ESA_MEMTYPE_MASK);
1003	bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_INDEX, index);
1004	data = bus_space_read_2(iot, ioh, ESA_DSP_PORT_MEMORY_DATA);
1005
1006	return (data);
1007}
1008
1009void
1010esa_write_assp(struct esa_softc *sc, u_int16_t region, u_int16_t index,
1011		u_int16_t data)
1012{
1013	bus_space_tag_t iot = sc->sc_iot;
1014	bus_space_handle_t ioh = sc->sc_ioh;
1015
1016	bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_TYPE,
1017	    region & ESA_MEMTYPE_MASK);
1018	bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_INDEX, index);
1019	bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_DATA, data);
1020
1021	return;
1022}
1023
1024int
1025esa_init_codec(struct esa_softc *sc)
1026{
1027	bus_space_tag_t iot = sc->sc_iot;
1028	bus_space_handle_t ioh = sc->sc_ioh;
1029	u_int32_t data;
1030
1031	data = bus_space_read_1(iot, ioh, ESA_CODEC_COMMAND);
1032
1033	return ((data & 0x1) ? 0 : 1);
1034}
1035
1036int
1037esa_attach_codec(void *aux, struct ac97_codec_if *codec_if)
1038{
1039	struct esa_softc *sc = aux;
1040
1041	sc->codec_if = codec_if;
1042
1043	return (0);
1044}
1045
1046int
1047esa_read_codec(void *aux, u_int8_t reg, u_int16_t *result)
1048{
1049	struct esa_softc *sc = aux;
1050	bus_space_tag_t iot = sc->sc_iot;
1051	bus_space_handle_t ioh = sc->sc_ioh;
1052
1053	if (esa_wait(sc))
1054		printf("%s: esa_read_codec: timed out\n", sc->sc_dev.dv_xname);
1055	bus_space_write_1(iot, ioh, ESA_CODEC_COMMAND, (reg & 0x7f) | 0x80);
1056	delay(50);
1057	if (esa_wait(sc))
1058		printf("%s: esa_read_codec: timed out\n", sc->sc_dev.dv_xname);
1059	*result = bus_space_read_2(iot, ioh, ESA_CODEC_DATA);
1060
1061	return (0);
1062}
1063
1064int
1065esa_write_codec(void *aux, u_int8_t reg, u_int16_t data)
1066{
1067	struct esa_softc *sc = aux;
1068	bus_space_tag_t iot = sc->sc_iot;
1069	bus_space_handle_t ioh = sc->sc_ioh;
1070
1071	if (esa_wait(sc)) {
1072		printf("%s: esa_write_codec: timed out\n", sc->sc_dev.dv_xname);
1073		return (-1);
1074	}
1075	bus_space_write_2(iot, ioh, ESA_CODEC_DATA, data);
1076	bus_space_write_1(iot, ioh, ESA_CODEC_COMMAND, reg & 0x7f);
1077	delay(50);
1078
1079	return (0);
1080}
1081
1082void
1083esa_reset_codec(void *aux)
1084{
1085
1086	return;
1087}
1088
1089enum ac97_host_flags
1090esa_flags_codec(void *aux)
1091{
1092	struct esa_softc *sc = aux;
1093
1094	return (sc->codec_flags);
1095}
1096
1097int
1098esa_wait(struct esa_softc *sc)
1099{
1100	int i, val;
1101	bus_space_tag_t iot = sc->sc_iot;
1102	bus_space_handle_t ioh = sc->sc_ioh;
1103
1104	for (i = 0; i < 20; i++) {
1105		val = bus_space_read_1(iot, ioh, ESA_CODEC_STATUS);
1106		if ((val & 1) == 0)
1107			return (0);
1108		delay(2);
1109	}
1110
1111	return (-1);
1112}
1113
1114int
1115esa_init(struct esa_softc *sc)
1116{
1117	bus_space_tag_t iot = sc->sc_iot;
1118	bus_space_handle_t ioh = sc->sc_ioh;
1119	pcitag_t tag = sc->sc_tag;
1120	pci_chipset_tag_t pc = sc->sc_pct;
1121	u_int32_t data, i, size;
1122	u_int8_t reset_state;
1123	int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) +
1124			   (ESA_MINISRC_IN_BUFFER_SIZE & ~1) +
1125			   (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255)
1126			   &~ 255;
1127
1128	/* Disable legacy emulation */
1129	data = pci_conf_read(pc, tag, PCI_LEGACY_AUDIO_CTRL);
1130	data |= DISABLE_LEGACY;
1131	pci_conf_write(pc, tag, PCI_LEGACY_AUDIO_CTRL, data);
1132
1133	esa_config(sc);
1134
1135	reset_state = esa_assp_halt(sc);
1136
1137	esa_init_codec(sc);
1138	esa_codec_reset(sc);
1139
1140	/* Zero kernel and mixer data */
1141	size = ESA_REV_B_DATA_MEMORY_UNIT_LENGTH * ESA_NUM_UNITS_KERNEL_DATA;
1142	for (i = 0; i < size / 2; i++) {
1143		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
1144		    ESA_KDATA_BASE_ADDR + i, 0);
1145		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
1146		    ESA_KDATA_BASE_ADDR2 + i, 0);
1147	}
1148
1149	/* Init DMA pointer */
1150	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_CURRENT_DMA,
1151	    ESA_KDATA_DMA_XFER0);
1152
1153	/* Write kernel code into memory */
1154	size = sizeof(esa_assp_kernel_image);
1155	for (i = 0; i < size / 2; i++)
1156		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE,
1157		    ESA_REV_B_CODE_MEMORY_BEGIN + i, esa_assp_kernel_image[i]);
1158
1159	size = sizeof(esa_assp_minisrc_image);
1160	for (i = 0; i < size / 2; i++)
1161		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 0x400 + i,
1162		    esa_assp_minisrc_image[i]);
1163
1164	/* Write the coefficients for the low pass filter */
1165	size = sizeof(esa_minisrc_lpf_image);
1166	for (i = 0; i < size / 2; i++)
1167		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE,
1168		    0x400 + ESA_MINISRC_COEF_LOC + i, esa_minisrc_lpf_image[i]);
1169	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE,
1170	    0x400 + ESA_MINISRC_COEF_LOC + size, 0x8000);
1171	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_TASK0, 0x400);
1172	/* Init the mixer number */
1173	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
1174             ESA_KDATA_MIXER_TASK_NUMBER, 0);
1175	/* Extreme kernel master volume */
1176	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DAC_LEFT_VOLUME,
1177	    ESA_ARB_VOLUME);
1178	esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
1179            ESA_KDATA_DAC_RIGHT_VOLUME, ESA_ARB_VOLUME);
1180
1181	if (esa_amp_enable(sc))
1182		return (-1);
1183
1184	/* Zero entire DAC/ADC area */
1185	for (i = 0x1100; i < 0x1c00; i++)
1186		esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, i, 0);
1187
1188	/* set some sane defaults */
1189	sc->play.data_offset = ESA_DAC_DATA + data_bytes;
1190	sc->rec.data_offset = ESA_DAC_DATA + data_bytes + (data_bytes / 2);
1191
1192	esa_enable_interrupts(sc);
1193
1194	bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B,
1195	    reset_state | ESA_REGB_ENABLE_RESET);
1196
1197	return (0);
1198}
1199
1200void
1201esa_config(struct esa_softc *sc)
1202{
1203	bus_space_tag_t iot = sc->sc_iot;
1204	bus_space_handle_t ioh = sc->sc_ioh;
1205	pcitag_t tag = sc->sc_tag;
1206	pci_chipset_tag_t pc = sc->sc_pct;
1207	u_int32_t data;
1208
1209	data = pci_conf_read(pc, tag, ESA_PCI_ALLEGRO_CONFIG);
1210	data &= ESA_REDUCED_DEBOUNCE;
1211	data |= ESA_PM_CTRL_ENABLE | ESA_CLK_DIV_BY_49 | ESA_USE_PCI_TIMING;
1212	pci_conf_write(pc, tag, ESA_PCI_ALLEGRO_CONFIG, data);
1213
1214	bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_B, ESA_RESET_ASSP);
1215	data = pci_conf_read(pc, tag, ESA_PCI_ALLEGRO_CONFIG);
1216	data &= ~ESA_INT_CLK_SELECT;
1217	if (sc->type == ESS_MAESTRO3) {
1218		data &= ~ESA_INT_CLK_MULT_ENABLE;
1219		data |= ESA_INT_CLK_SRC_NOT_PCI;
1220	}
1221	data &= ~(ESA_CLK_MULT_MODE_SELECT | ESA_CLK_MULT_MODE_SELECT_2);
1222	pci_conf_write(pc, tag, ESA_PCI_ALLEGRO_CONFIG, data);
1223
1224	if (sc->type == ESS_ALLEGRO1) {
1225		data = pci_conf_read(pc, tag, ESA_PCI_USER_CONFIG);
1226		data |= ESA_IN_CLK_12MHZ_SELECT;
1227		pci_conf_write(pc, tag, ESA_PCI_USER_CONFIG, data);
1228	}
1229
1230	data = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_A);
1231	data &= ~(ESA_DSP_CLK_36MHZ_SELECT | ESA_ASSP_CLK_49MHZ_SELECT);
1232	data |= ESA_ASSP_CLK_49MHZ_SELECT;	/* XXX: Assumes 49MHz DSP */
1233	data |= ESA_ASSP_0_WS_ENABLE;
1234	bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_A, data);
1235
1236	bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_B, ESA_RUN_ASSP);
1237
1238	return;
1239}
1240
1241u_int8_t
1242esa_assp_halt(struct esa_softc *sc)
1243{
1244	bus_space_tag_t iot = sc->sc_iot;
1245	bus_space_handle_t ioh = sc->sc_ioh;
1246	u_int8_t data, reset_state;
1247
1248	data = bus_space_read_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B);
1249	reset_state = data & ~ESA_REGB_STOP_CLOCK;
1250	delay(10000);		/* XXX use tsleep */
1251	bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B,
1252			reset_state & ~ESA_REGB_ENABLE_RESET);
1253	delay(10000);		/* XXX use tsleep */
1254
1255	return (reset_state);
1256}
1257
1258void
1259esa_codec_reset(struct esa_softc *sc)
1260{
1261	bus_space_tag_t iot = sc->sc_iot;
1262	bus_space_handle_t ioh = sc->sc_ioh;
1263	u_int16_t data, dir;
1264	int retry = 0;
1265
1266	do {
1267		data = bus_space_read_2(iot, ioh, ESA_GPIO_DIRECTION);
1268		dir = data | 0x10; /* assuming pci bus master? */
1269
1270		/* remote codec config */
1271		data = bus_space_read_2(iot, ioh, ESA_RING_BUS_CTRL_B);
1272		bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_B,
1273		    data & ~ESA_SECOND_CODEC_ID_MASK);
1274		data = bus_space_read_2(iot, ioh, ESA_SDO_OUT_DEST_CTRL);
1275		bus_space_write_2(iot, ioh, ESA_SDO_OUT_DEST_CTRL,
1276		    data & ~ESA_COMMAND_ADDR_OUT);
1277		data = bus_space_read_2(iot, ioh, ESA_SDO_IN_DEST_CTRL);
1278		bus_space_write_2(iot, ioh, ESA_SDO_IN_DEST_CTRL,
1279		    data & ~ESA_STATUS_ADDR_IN);
1280
1281		bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_A,
1282				  ESA_IO_SRAM_ENABLE);
1283		delay(20);
1284
1285		bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION,
1286		    dir & ~ESA_GPO_PRIMARY_AC97);
1287		bus_space_write_2(iot, ioh, ESA_GPIO_MASK,
1288				  ~ESA_GPO_PRIMARY_AC97);
1289		bus_space_write_2(iot, ioh, ESA_GPIO_DATA, 0);
1290		bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION,
1291		    dir | ESA_GPO_PRIMARY_AC97);
1292		delay(sc->delay1 * 1000);
1293		bus_space_write_2(iot, ioh, ESA_GPIO_DATA,
1294				  ESA_GPO_PRIMARY_AC97);
1295		delay(5);
1296		bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_A,
1297		    ESA_IO_SRAM_ENABLE | ESA_SERIAL_AC_LINK_ENABLE);
1298		bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~0);
1299		delay(sc->delay2 * 1000);
1300
1301		esa_read_codec(sc, 0x7c, &data);
1302		if ((data == 0) || (data == 0xffff)) {
1303			retry++;
1304			if (retry > 3) {
1305				printf("%s: esa_codec_reset: failed\n",
1306				    sc->sc_dev.dv_xname);
1307				break;
1308			}
1309			printf("%s: esa_codec_reset: retrying\n",
1310			    sc->sc_dev.dv_xname);
1311		} else
1312			retry = 0;
1313	} while (retry);
1314
1315	return;
1316}
1317
1318int
1319esa_amp_enable(struct esa_softc *sc)
1320{
1321	bus_space_tag_t iot = sc->sc_iot;
1322	bus_space_handle_t ioh = sc->sc_ioh;
1323	u_int32_t gpo, polarity_port, polarity;
1324	u_int16_t data;
1325
1326	switch (sc->type) {
1327	case ESS_ALLEGRO1:
1328		polarity_port = 0x1800;
1329		break;
1330	case ESS_MAESTRO3:
1331		polarity_port = 0x1100;
1332		break;
1333	default:
1334		printf("%s: esa_amp_enable: Unknown chip type!!!\n",
1335		    sc->sc_dev.dv_xname);
1336		return (1);
1337	}
1338
1339	gpo = (polarity_port >> 8) & 0x0f;
1340	polarity = polarity_port >> 12;
1341	polarity = !polarity;	/* Enable */
1342	polarity = polarity << gpo;
1343	gpo = 1 << gpo;
1344	bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~gpo);
1345	data = bus_space_read_2(iot, ioh, ESA_GPIO_DIRECTION);
1346	bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION, data | gpo);
1347	data = ESA_GPO_SECONDARY_AC97 | ESA_GPO_PRIMARY_AC97 | polarity;
1348	bus_space_write_2(iot, ioh, ESA_GPIO_DATA, data);
1349	bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~0);
1350
1351	return (0);
1352}
1353
1354void
1355esa_enable_interrupts(struct esa_softc *sc)
1356{
1357	bus_space_tag_t iot = sc->sc_iot;
1358	bus_space_handle_t ioh = sc->sc_ioh;
1359	u_int8_t data;
1360
1361	bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL,
1362	    ESA_ASSP_INT_ENABLE | ESA_HV_INT_ENABLE);
1363	data = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_C);
1364	bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_C,
1365	    data | ESA_ASSP_HOST_INT_ENABLE);
1366}
1367
1368int
1369esa_power(struct esa_softc *sc, int state)
1370{
1371	pcitag_t tag = sc->sc_tag;
1372	pci_chipset_tag_t pc = sc->sc_pct;
1373	u_int32_t data;
1374
1375	data = pci_conf_read(pc, tag, 0x34);
1376	if (pci_conf_read(pc, tag, data) == 1)
1377		pci_conf_write(pc, tag, data + 4, state);
1378
1379	return (0);
1380}
1381
1382u_int32_t
1383esa_get_pointer(struct esa_softc *sc, struct esa_channel *ch)
1384{
1385	u_int16_t hi = 0, lo = 0;
1386	u_int32_t addr;
1387	int data_offset = ch->data_offset;
1388
1389	hi = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, data_offset +
1390	    ESA_CDATA_HOST_SRC_CURRENTH);
1391	lo = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, data_offset +
1392	    ESA_CDATA_HOST_SRC_CURRENTL);
1393
1394	addr = lo | ((u_int32_t)hi << 16);
1395	return (addr - ch->start);
1396}
1397
1398paddr_t
1399esa_mappage(void *addr, void *mem, off_t off, int prot)
1400{
1401	struct esa_softc *sc = addr;
1402	struct esa_dma *p;
1403
1404	if (off < 0)
1405		return (-1);
1406	for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next)
1407		;
1408	if (!p)
1409		return (-1);
1410	return (bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nsegs,
1411				off, prot, BUS_DMA_WAITOK));
1412}
1413
1414