xref: /openbsd-src/sys/dev/pci/yds.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 /*	$OpenBSD: yds.c,v 1.52 2015/12/11 16:07:02 mpi Exp $	*/
2 /*	$NetBSD: yds.c,v 1.5 2001/05/21 23:55:04 minoura Exp $	*/
3 
4 /*
5  * Copyright (c) 2000, 2001 Kazuki Sakamoto and Minoura Makoto.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * Yamaha YMF724[B-F]/740[B-C]/744/754
31  *
32  * Documentation links:
33  * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/
34  * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/pci/
35  *
36  * TODO:
37  * - FM synth volume (difficult: mixed before ac97)
38  * - Digital in/out (SPDIF) support
39  * - Effect??
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/fcntl.h>
46 #include <sys/malloc.h>
47 #include <sys/device.h>
48 #include <sys/queue.h>
49 
50 #include <dev/pci/pcidevs.h>
51 #include <dev/pci/pcireg.h>
52 #include <dev/pci/pcivar.h>
53 
54 #include <sys/audioio.h>
55 #include <dev/audio_if.h>
56 #include <dev/midi_if.h>
57 #include <dev/ic/ac97.h>
58 
59 #include <machine/bus.h>
60 #include <machine/intr.h>
61 
62 #include <dev/pci/ydsreg.h>
63 #include <dev/pci/ydsvar.h>
64 
65 /* Debug */
66 #undef YDS_USE_REC_SLOT
67 #define YDS_USE_P44
68 
69 #ifdef AUDIO_DEBUG
70 # define DPRINTF(x)	if (ydsdebug) printf x
71 # define DPRINTFN(n,x)	if (ydsdebug>(n)) printf x
72 int	ydsdebug = 0;
73 #else
74 # define DPRINTF(x)
75 # define DPRINTFN(n,x)
76 #endif
77 #ifdef YDS_USE_REC_SLOT
78 # define YDS_INPUT_SLOT 0	/* REC slot = ADC + loopbacks */
79 #else
80 # define YDS_INPUT_SLOT 1	/* ADC slot */
81 #endif
82 
83 static	int ac97_id2;
84 
85 int	yds_match(struct device *, void *, void *);
86 void	yds_attach(struct device *, struct device *, void *);
87 int	yds_activate(struct device *, int);
88 int	yds_intr(void *);
89 
90 static void nswaph(u_int32_t *p, int wcount);
91 
92 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
93 #define KERNADDR(p) ((void *)((p)->addr))
94 
95 int	yds_allocmem(struct yds_softc *, size_t, size_t,
96 	    struct yds_dma *);
97 int	yds_freemem(struct yds_softc *, struct yds_dma *);
98 
99 #ifndef AUDIO_DEBUG
100 #define YWRITE1(sc, r, x) bus_space_write_1((sc)->memt, (sc)->memh, (r), (x))
101 #define YWRITE2(sc, r, x) bus_space_write_2((sc)->memt, (sc)->memh, (r), (x))
102 #define YWRITE4(sc, r, x) bus_space_write_4((sc)->memt, (sc)->memh, (r), (x))
103 #define YREAD1(sc, r) bus_space_read_1((sc)->memt, (sc)->memh, (r))
104 #define YREAD2(sc, r) bus_space_read_2((sc)->memt, (sc)->memh, (r))
105 #define YREAD4(sc, r) bus_space_read_4((sc)->memt, (sc)->memh, (r))
106 #else
107 
108 u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r);
109 u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r);
110 void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x);
111 void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x);
112 void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x);
113 
114 u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r)
115 {
116   DPRINTFN(5, (" YREAD2(0x%lX)\n",(unsigned long)r));
117   return bus_space_read_2(sc->memt,sc->memh,r);
118 }
119 u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r)
120 {
121   DPRINTFN(5, (" YREAD4(0x%lX)\n",(unsigned long)r));
122   return bus_space_read_4(sc->memt,sc->memh,r);
123 }
124 void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x)
125 {
126   DPRINTFN(5, (" YWRITE1(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
127   bus_space_write_1(sc->memt,sc->memh,r,x);
128 }
129 void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x)
130 {
131   DPRINTFN(5, (" YWRITE2(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
132   bus_space_write_2(sc->memt,sc->memh,r,x);
133 }
134 void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x)
135 {
136   DPRINTFN(5, (" YWRITE4(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
137   bus_space_write_4(sc->memt,sc->memh,r,x);
138 }
139 #endif
140 
141 #define	YWRITEREGION4(sc, r, x, c)	\
142 	bus_space_write_region_4((sc)->memt, (sc)->memh, (r), (x), (c) / 4)
143 
144 struct cfattach yds_ca = {
145 	sizeof(struct yds_softc), yds_match, yds_attach, NULL,
146 	yds_activate
147 };
148 
149 struct cfdriver yds_cd = {
150 	NULL, "yds", DV_DULL
151 };
152 
153 int	yds_open(void *, int);
154 void	yds_close(void *);
155 int	yds_query_encoding(void *, struct audio_encoding *);
156 int	yds_set_params(void *, int, int,
157 	    struct audio_params *, struct audio_params *);
158 void	yds_get_default_params(void *, int, struct audio_params *);
159 int	yds_round_blocksize(void *, int);
160 int	yds_trigger_output(void *, void *, void *, int, void (*)(void *),
161 	    void *, struct audio_params *);
162 int	yds_trigger_input(void *, void *, void *, int, void (*)(void *),
163 	    void *, struct audio_params *);
164 int	yds_halt_output(void *);
165 int	yds_halt_input(void *);
166 int	yds_getdev(void *, struct audio_device *);
167 int	yds_mixer_set_port(void *, mixer_ctrl_t *);
168 int	yds_mixer_get_port(void *, mixer_ctrl_t *);
169 void   *yds_malloc(void *, int, size_t, int, int);
170 void	yds_free(void *, void *, int);
171 size_t	yds_round_buffersize(void *, int, size_t);
172 paddr_t	yds_mappage(void *, void *, off_t, int);
173 int	yds_get_props(void *);
174 int	yds_query_devinfo(void *addr, mixer_devinfo_t *dip);
175 
176 int     yds_attach_codec(void *sc, struct ac97_codec_if *);
177 int	yds_read_codec(void *sc, u_int8_t a, u_int16_t *d);
178 int	yds_write_codec(void *sc, u_int8_t a, u_int16_t d);
179 void    yds_reset_codec(void *sc);
180 int     yds_get_portnum_by_name(struct yds_softc *, char *, char *,
181 	    char *);
182 
183 static u_int yds_get_dstype(int);
184 static int yds_download_mcode(struct yds_softc *);
185 static int yds_allocate_slots(struct yds_softc *, int);
186 static void yds_configure_legacy(struct yds_softc *arg);
187 static void yds_enable_dsp(struct yds_softc *);
188 static int yds_disable_dsp(struct yds_softc *);
189 static int yds_ready_codec(struct yds_codec_softc *);
190 static int yds_halt(struct yds_softc *);
191 static u_int32_t yds_get_lpfq(u_int);
192 static u_int32_t yds_get_lpfk(u_int);
193 static struct yds_dma *yds_find_dma(struct yds_softc *, void *);
194 
195 int	yds_init(struct yds_softc *, int);
196 void	yds_attachhook(struct device *);
197 
198 #ifdef AUDIO_DEBUG
199 static void yds_dump_play_slot(struct yds_softc *, int);
200 #define	YDS_DUMP_PLAY_SLOT(n,sc,bank) \
201 	if (ydsdebug > (n)) yds_dump_play_slot(sc, bank)
202 #else
203 #define	YDS_DUMP_PLAY_SLOT(n,sc,bank)
204 #endif /* AUDIO_DEBUG */
205 
206 static struct audio_hw_if yds_hw_if = {
207 	yds_open,
208 	yds_close,
209 	NULL,
210 	yds_query_encoding,
211 	yds_set_params,
212 	yds_round_blocksize,
213 	NULL,
214 	NULL,
215 	NULL,
216 	NULL,
217 	NULL,
218 	yds_halt_output,
219 	yds_halt_input,
220 	NULL,
221 	yds_getdev,
222 	NULL,
223 	yds_mixer_set_port,
224 	yds_mixer_get_port,
225 	yds_query_devinfo,
226 	yds_malloc,
227 	yds_free,
228 	yds_round_buffersize,
229 	yds_mappage,
230 	yds_get_props,
231 	yds_trigger_output,
232 	yds_trigger_input,
233 	yds_get_default_params
234 };
235 
236 struct audio_device yds_device = {
237 	"Yamaha DS-1",
238 	"",
239 	"yds"
240 };
241 
242 const static struct {
243 	u_int	id;
244 	u_int	flags;
245 #define YDS_CAP_MCODE_1			0x0001
246 #define YDS_CAP_MCODE_1E		0x0002
247 #define YDS_CAP_LEGACY_SELECTABLE	0x0004
248 #define YDS_CAP_LEGACY_FLEXIBLE		0x0008
249 #define YDS_CAP_HAS_P44			0x0010
250 #define YDS_CAP_LEGACY_SMOD_DISABLE	0x1000
251 } yds_chip_capability_list[] = {
252 	{ PCI_PRODUCT_YAMAHA_YMF724,
253 	  YDS_CAP_MCODE_1|YDS_CAP_LEGACY_SELECTABLE },
254 	/* 740[C] has only 32 slots.  But anyway we use only 2 */
255 	{ PCI_PRODUCT_YAMAHA_YMF740,
256 	  YDS_CAP_MCODE_1|YDS_CAP_LEGACY_SELECTABLE },	/* XXX NOT TESTED */
257 	{ PCI_PRODUCT_YAMAHA_YMF740C,
258 	  YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_SELECTABLE },
259 	{ PCI_PRODUCT_YAMAHA_YMF724F,
260 	  YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_SELECTABLE },
261 	{ PCI_PRODUCT_YAMAHA_YMF744,
262 	  YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_FLEXIBLE },
263 	{ PCI_PRODUCT_YAMAHA_YMF754,
264 	  YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_FLEXIBLE|YDS_CAP_HAS_P44 },
265 	/* How about 734/737/738?? */
266 	{ 0, 0 }
267 };
268 #ifdef AUDIO_DEBUG
269 #define YDS_CAP_BITS	"\020\005P44\004LEGFLEX\003LEGSEL\002MCODE1E\001MCODE1"
270 #endif
271 
272 #ifdef AUDIO_DEBUG
273 static void
274 yds_dump_play_slot(struct yds_softc *sc, int bank)
275 {
276 	int i, j;
277 	u_int32_t *p;
278 	u_int32_t num;
279 	struct yds_dma *dma;
280 
281 	for (i = 0; i < N_PLAY_SLOTS; i++) {
282 		printf("pbankp[%d] = %p,", i*2, sc->pbankp[i*2]);
283 		printf("pbankp[%d] = %p\n", i*2+1, sc->pbankp[i*2+1]);
284 	}
285 
286 	p = (u_int32_t*)sc->ptbl;
287 	for (i = 0; i < N_PLAY_SLOTS+1; i++) {
288 		printf("ptbl + %d:0x%x\n", i, *p);
289 		p++;
290 	}
291 
292 	num = *(u_int32_t*)sc->ptbl;
293 	printf("num = %d\n", num);
294 
295 	for (i = 0; i < num; i++) {
296 
297 		p = (u_int32_t *)sc->pbankp[i];
298 
299 		dma = yds_find_dma(sc,(void *)p);
300 
301 		for (j = 0; j < sizeof(struct play_slot_ctrl_bank) /
302 		    sizeof(u_int32_t); j++) {
303 			printf("    0x%02x: 0x%08x\n",
304 			       (unsigned) (j * sizeof(u_int32_t)),
305 			       (unsigned) *p++);
306 		}
307 		/*
308 		p = (u_int32_t *)sc->pbankp[i*2 + 1];
309 		printf("  pbankp[%d] : %p\n", i*2 + 1, p);
310 		for (j = 0; j < sizeof(struct play_slot_ctrl_bank) /
311 		    sizeof(u_int32_t); j++) {
312 			printf("    0x%02x: 0x%08x\n",
313 				j * sizeof(u_int32_t), *p++);
314 				delay(1);
315 		}
316 		*/
317 	}
318 }
319 #endif /* AUDIO_DEBUG */
320 
321 static u_int
322 yds_get_dstype(int id)
323 {
324 	int i;
325 
326 	for (i = 0; yds_chip_capability_list[i].id; i++) {
327 		if (PCI_PRODUCT(id) == yds_chip_capability_list[i].id)
328 			return yds_chip_capability_list[i].flags;
329 	}
330 
331 	return -1;
332 }
333 
334 static void
335 nswaph(u_int32_t *p, int wcount)
336 {
337 	for (; wcount; wcount -=4) {
338 		*p = ntohl(*p);
339 		p++;
340 	}
341 }
342 
343 static int
344 yds_download_mcode(struct yds_softc *sc)
345 {
346 	u_int ctrl;
347 	const u_int32_t *p;
348 	size_t size;
349 	u_char *buf;
350 	size_t buflen;
351 	int error;
352 	struct yds_firmware *yf;
353 
354 	error = loadfirmware("yds", &buf, &buflen);
355 	if (error)
356 		return 1;
357 	yf = (struct yds_firmware *)buf;
358 
359 	if (sc->sc_flags & YDS_CAP_MCODE_1) {
360 		p = (u_int32_t *)&yf->data[ntohl(yf->dsplen)];
361 		size = ntohl(yf->ds1len);
362 	} else if (sc->sc_flags & YDS_CAP_MCODE_1E) {
363 		p = (u_int32_t *)&yf->data[ntohl(yf->dsplen) + ntohl(yf->ds1len)];
364 		size = ntohl(yf->ds1elen);
365 	} else {
366 		free(buf, M_DEVBUF, buflen);
367 		return 1;	/* unknown */
368 	}
369 
370 	if (size > buflen) {
371 		printf("%s: old firmware file, update please\n",
372 		    sc->sc_dev.dv_xname);
373 		free(buf, M_DEVBUF, buflen);
374 		return 1;
375 	}
376 
377 	if (yds_disable_dsp(sc)) {
378 		free(buf, M_DEVBUF, buflen);
379 		return 1;
380 	}
381 
382 	/* Software reset */
383         YWRITE4(sc, YDS_MODE, YDS_MODE_RESET);
384         YWRITE4(sc, YDS_MODE, 0);
385 
386         YWRITE4(sc, YDS_MAPOF_REC, 0);
387         YWRITE4(sc, YDS_MAPOF_EFFECT, 0);
388         YWRITE4(sc, YDS_PLAY_CTRLBASE, 0);
389         YWRITE4(sc, YDS_REC_CTRLBASE, 0);
390         YWRITE4(sc, YDS_EFFECT_CTRLBASE, 0);
391         YWRITE4(sc, YDS_WORK_BASE, 0);
392 
393         ctrl = YREAD2(sc, YDS_GLOBAL_CONTROL);
394         YWRITE2(sc, YDS_GLOBAL_CONTROL, ctrl & ~0x0007);
395 
396 	/* Download DSP microcode. */
397 	nswaph((u_int32_t *)&yf->data[0], ntohl(yf->dsplen));
398 	YWRITEREGION4(sc, YDS_DSP_INSTRAM, (u_int32_t *)&yf->data[0],
399 	    ntohl(yf->dsplen));
400 
401 	/* Download CONTROL microcode. */
402 	nswaph((u_int32_t *)p, size);
403 	YWRITEREGION4(sc, YDS_CTRL_INSTRAM, p, size);
404 
405 	yds_enable_dsp(sc);
406 	delay(10*1000);		/* neccesary on my 724F (??) */
407 
408 	free(buf, M_DEVBUF, buflen);
409 	return 0;
410 }
411 
412 static int
413 yds_allocate_slots(struct yds_softc *sc, int resuming)
414 {
415 	size_t pcs, rcs, ecs, ws, memsize;
416 	void *mp;
417 	u_int32_t da;		/* DMA address */
418 	char *va;		/* KVA */
419 	off_t cb;
420 	int i;
421 	struct yds_dma *p;
422 
423 	/* Alloc DSP Control Data */
424 	pcs = YREAD4(sc, YDS_PLAY_CTRLSIZE) * sizeof(u_int32_t);
425 	rcs = YREAD4(sc, YDS_REC_CTRLSIZE) * sizeof(u_int32_t);
426 	ecs = YREAD4(sc, YDS_EFFECT_CTRLSIZE) * sizeof(u_int32_t);
427 	ws = WORK_SIZE;
428 	YWRITE4(sc, YDS_WORK_SIZE, ws / sizeof(u_int32_t));
429 
430 	DPRINTF(("play control size : %d\n", (unsigned int)pcs));
431 	DPRINTF(("rec control size : %d\n", (unsigned int)rcs));
432 	DPRINTF(("eff control size : %d\n", (unsigned int)ecs));
433 	DPRINTF(("work size : %d\n", (unsigned int)ws));
434 #ifdef DIAGNOSTIC
435 	if (pcs != sizeof(struct play_slot_ctrl_bank)) {
436 		printf("%s: invalid play slot ctrldata %d != %d\n",
437 		       sc->sc_dev.dv_xname, (unsigned int)pcs,
438 		       (unsigned int)sizeof(struct play_slot_ctrl_bank));
439 	}
440 	if (rcs != sizeof(struct rec_slot_ctrl_bank)) {
441 		printf("%s: invalid rec slot ctrldata %d != %d\n",
442 		       sc->sc_dev.dv_xname, (unsigned int)rcs,
443 		       (unsigned int)sizeof(struct rec_slot_ctrl_bank));
444         }
445 #endif
446 
447 	memsize = N_PLAY_SLOTS*N_PLAY_SLOT_CTRL_BANK*pcs +
448 		  N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK*rcs + ws;
449 	memsize += (N_PLAY_SLOTS+1)*sizeof(u_int32_t);
450 
451 	p = &sc->sc_ctrldata;
452 	if (!resuming) {
453 		i = yds_allocmem(sc, memsize, 16, p);
454 		if (i) {
455 			printf("%s: couldn't alloc/map DSP DMA buffer, reason %d\n",
456 			       sc->sc_dev.dv_xname, i);
457 			free(p, M_DEVBUF, 0);
458 			return 1;
459 		}
460 	}
461 	mp = KERNADDR(p);
462 	da = DMAADDR(p);
463 
464 	DPRINTF(("mp:%p, DMA addr:%p\n",
465 		 mp, (void *) sc->sc_ctrldata.map->dm_segs[0].ds_addr));
466 
467 	bzero(mp, memsize);
468 
469 	/* Work space */
470         cb = 0;
471 	va = (u_int8_t*)mp;
472 	YWRITE4(sc, YDS_WORK_BASE, da + cb);
473         cb += ws;
474 
475 	/* Play control data table */
476         sc->ptbl = (u_int32_t *)(va + cb);
477 	sc->ptbloff = cb;
478         YWRITE4(sc, YDS_PLAY_CTRLBASE, da + cb);
479         cb += (N_PLAY_SLOT_CTRL + 1) * sizeof(u_int32_t);
480 
481 	/* Record slot control data */
482         sc->rbank = (struct rec_slot_ctrl_bank *)(va + cb);
483         YWRITE4(sc, YDS_REC_CTRLBASE, da + cb);
484 	sc->rbankoff = cb;
485         cb += N_REC_SLOT_CTRL * N_REC_SLOT_CTRL_BANK * rcs;
486 
487 #if 0
488 	/* Effect slot control data -- unused */
489         YWRITE4(sc, YDS_EFFECT_CTRLBASE, da + cb);
490         cb += N_EFFECT_SLOT_CTRL * N_EFFECT_SLOT_CTRL_BANK * ecs;
491 #endif
492 
493 	/* Play slot control data */
494         sc->pbankoff = da + cb;
495         for (i=0; i<N_PLAY_SLOT_CTRL; i++) {
496 		sc->pbankp[i*2] = (struct play_slot_ctrl_bank *)(va + cb);
497 		*(sc->ptbl + i+1) = da + cb;
498                 cb += pcs;
499 
500                 sc->pbankp[i*2+1] = (struct play_slot_ctrl_bank *)(va + cb);
501                 cb += pcs;
502         }
503 	/* Sync play control data table */
504 	bus_dmamap_sync(sc->sc_dmatag, p->map,
505 			sc->ptbloff, (N_PLAY_SLOT_CTRL+1) * sizeof(u_int32_t),
506 			BUS_DMASYNC_PREWRITE);
507 
508 	return 0;
509 }
510 
511 static void
512 yds_enable_dsp(struct yds_softc *sc)
513 {
514 	YWRITE4(sc, YDS_CONFIG, YDS_DSP_SETUP);
515 }
516 
517 static int
518 yds_disable_dsp(struct yds_softc *sc)
519 {
520 	int to;
521 	u_int32_t data;
522 
523 	data = YREAD4(sc, YDS_CONFIG);
524 	if (data)
525 		YWRITE4(sc, YDS_CONFIG, YDS_DSP_DISABLE);
526 
527 	for (to = 0; to < YDS_WORK_TIMEOUT; to++) {
528 		if ((YREAD4(sc, YDS_STATUS) & YDS_STAT_WORK) == 0)
529 			return 0;
530 		delay(1);
531 	}
532 
533 	return 1;
534 }
535 
536 int
537 yds_match(struct device *parent, void *match, void *aux)
538 {
539 	struct pci_attach_args *pa = (struct pci_attach_args *) aux;
540 
541 	switch (PCI_VENDOR(pa->pa_id)) {
542 	case PCI_VENDOR_YAMAHA:
543 		switch (PCI_PRODUCT(pa->pa_id)) {
544 		case PCI_PRODUCT_YAMAHA_YMF724:
545 		case PCI_PRODUCT_YAMAHA_YMF740:
546 		case PCI_PRODUCT_YAMAHA_YMF740C:
547 		case PCI_PRODUCT_YAMAHA_YMF724F:
548 		case PCI_PRODUCT_YAMAHA_YMF744:
549 		case PCI_PRODUCT_YAMAHA_YMF754:
550 		/* 734, 737, 738?? */
551 			return (1);
552 		}
553 		break;
554 	}
555 
556 	return (0);
557 }
558 
559 /*
560  * This routine is called after all the ISA devices are configured,
561  * to avoid conflict.
562  */
563 static void
564 yds_configure_legacy(struct yds_softc *sc)
565 #define FLEXIBLE	(sc->sc_flags & YDS_CAP_LEGACY_FLEXIBLE)
566 #define SELECTABLE	(sc->sc_flags & YDS_CAP_LEGACY_SELECTABLE)
567 {
568 	pcireg_t reg;
569 	struct device *dev;
570 	int i;
571 	bus_addr_t opl_addrs[] = {0x388, 0x398, 0x3A0, 0x3A8};
572 	bus_addr_t mpu_addrs[] = {0x330, 0x300, 0x332, 0x334};
573 
574 	if (!FLEXIBLE && !SELECTABLE)
575 		return;
576 
577 	reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY);
578 	reg &= ~0x8133c03f;	/* these bits are out of interest */
579 	reg |= (YDS_PCI_EX_LEGACY_IMOD | YDS_PCI_LEGACY_FMEN |
580 		YDS_PCI_LEGACY_MEN /*| YDS_PCI_LEGACY_MIEN*/);
581 	if (sc->sc_flags & YDS_CAP_LEGACY_SMOD_DISABLE)
582 		reg |= YDS_PCI_EX_LEGACY_SMOD_DISABLE;
583 	if (FLEXIBLE) {
584 		pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg);
585 		delay(100*1000);
586 	}
587 
588 	/* Look for OPL */
589 	dev = 0;
590 	for (i = 0; i < sizeof(opl_addrs) / sizeof (bus_addr_t); i++) {
591 		if (SELECTABLE) {
592 			pci_conf_write(sc->sc_pc, sc->sc_pcitag,
593 				       YDS_PCI_LEGACY, reg | (i << (0+16)));
594 			delay(100*1000);	/* wait 100ms */
595 		} else
596 			pci_conf_write(sc->sc_pc, sc->sc_pcitag,
597 				       YDS_PCI_FM_BA, opl_addrs[i]);
598 		if (bus_space_map(sc->sc_opl_iot,
599 				  opl_addrs[i], 4, 0, &sc->sc_opl_ioh) == 0) {
600 			struct audio_attach_args aa;
601 
602 			aa.type = AUDIODEV_TYPE_OPL;
603 			aa.hwif = aa.hdl = NULL;
604 			dev = config_found(&sc->sc_dev, &aa, audioprint);
605 			if (dev == 0)
606 				bus_space_unmap(sc->sc_opl_iot,
607 						sc->sc_opl_ioh, 4);
608 			else {
609 				if (SELECTABLE)
610 					reg |= (i << (0+16));
611 				break;
612 			}
613 		}
614 	}
615 	if (dev == 0) {
616 		reg &= ~YDS_PCI_LEGACY_FMEN;
617 		pci_conf_write(sc->sc_pc, sc->sc_pcitag,
618 			       YDS_PCI_LEGACY, reg);
619 	} else {
620 		/* Max. volume */
621 		YWRITE4(sc, YDS_LEGACY_OUT_VOLUME, 0x3fff3fff);
622 		YWRITE4(sc, YDS_LEGACY_REC_VOLUME, 0x3fff3fff);
623 	}
624 
625 	/* Look for MPU */
626 	dev = 0;
627 	for (i = 0; i < sizeof(mpu_addrs) / sizeof (bus_addr_t); i++) {
628 		if (SELECTABLE)
629 			pci_conf_write(sc->sc_pc, sc->sc_pcitag,
630 				       YDS_PCI_LEGACY, reg | (i << (4+16)));
631 		else
632 			pci_conf_write(sc->sc_pc, sc->sc_pcitag,
633 				       YDS_PCI_MPU_BA, mpu_addrs[i]);
634 		if (bus_space_map(sc->sc_mpu_iot,
635 				  mpu_addrs[i], 2, 0, &sc->sc_mpu_ioh) == 0) {
636 			struct audio_attach_args aa;
637 
638 			aa.type = AUDIODEV_TYPE_MPU;
639 			aa.hwif = aa.hdl = NULL;
640 			dev = config_found(&sc->sc_dev, &aa, audioprint);
641 			if (dev == 0)
642 				bus_space_unmap(sc->sc_mpu_iot,
643 						sc->sc_mpu_ioh, 2);
644 			else {
645 				if (SELECTABLE)
646 					reg |= (i << (4+16));
647 				break;
648 			}
649 		}
650 	}
651 	if (dev == 0) {
652 		reg &= ~(YDS_PCI_LEGACY_MEN | YDS_PCI_LEGACY_MIEN);
653 		pci_conf_write(sc->sc_pc, sc->sc_pcitag,
654 			       YDS_PCI_LEGACY, reg);
655 	}
656 	sc->sc_mpu = dev;
657 }
658 #undef FLEXIBLE
659 #undef SELECTABLE
660 
661 void
662 yds_attach(struct device *parent, struct device *self, void *aux)
663 {
664 	struct yds_softc *sc = (struct yds_softc *)self;
665 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
666 	pci_chipset_tag_t pc = pa->pa_pc;
667 	char const *intrstr;
668 	pci_intr_handle_t ih;
669 	bus_size_t size;
670 	pcireg_t reg;
671 	int i;
672 
673 	/* Map register to memory */
674 	if (pci_mapreg_map(pa, YDS_PCI_MBA, PCI_MAPREG_TYPE_MEM, 0,
675 	    &sc->memt, &sc->memh, NULL, &size, 0)) {
676 		printf(": can't map mem space\n");
677 		return;
678 	}
679 
680 	/* Map and establish the interrupt. */
681 	if (pci_intr_map(pa, &ih)) {
682 		printf(": couldn't map interrupt\n");
683 		bus_space_unmap(sc->memt, sc->memh, size);
684 		return;
685 	}
686 	intrstr = pci_intr_string(pc, ih);
687 	sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO | IPL_MPSAFE,
688 	    yds_intr, sc, self->dv_xname);
689 	if (sc->sc_ih == NULL) {
690 		printf(": couldn't establish interrupt");
691 		if (intrstr != NULL)
692 			printf(" at %s", intrstr);
693 		printf("\n");
694 		bus_space_unmap(sc->memt, sc->memh, size);
695 		return;
696 	}
697 	printf(": %s\n", intrstr);
698 
699 	sc->sc_dmatag = pa->pa_dmat;
700 	sc->sc_pc = pc;
701 	sc->sc_pcitag = pa->pa_tag;
702 	sc->sc_id = pa->pa_id;
703 	sc->sc_revision = PCI_REVISION(pa->pa_class);
704 	sc->sc_flags = yds_get_dstype(sc->sc_id);
705 	if (sc->sc_dev.dv_cfdata->cf_flags & YDS_CAP_LEGACY_SMOD_DISABLE)
706 		sc->sc_flags |= YDS_CAP_LEGACY_SMOD_DISABLE;
707 #ifdef AUDIO_DEBUG
708 	if (ydsdebug)
709 		printf("%s: chip has %b\n", sc->sc_dev.dv_xname,
710 		    sc->sc_flags, YDS_CAP_BITS);
711 #endif
712 
713 	/* Disable legacy mode */
714 	reg = pci_conf_read(pc, pa->pa_tag, YDS_PCI_LEGACY);
715 	pci_conf_write(pc, pa->pa_tag, YDS_PCI_LEGACY,
716 		       reg & YDS_PCI_LEGACY_LAD);
717 
718 	/* Mute all volumes */
719 	for (i = 0x80; i < 0xc0; i += 2)
720 		YWRITE2(sc, i, 0);
721 
722 	sc->sc_legacy_iot = pa->pa_iot;
723 	config_mountroot(self, yds_attachhook);
724 }
725 
726 void
727 yds_attachhook(struct device *self)
728 {
729 	struct yds_softc *sc = (struct yds_softc *)self;
730 	struct yds_codec_softc *codec;
731 	mixer_ctrl_t ctl;
732 	int r, i;
733 
734 	/* Initialize the device */
735 	if (yds_init(sc, 0) == -1)
736 		return;
737 
738 	/*
739 	 * Attach ac97 codec
740 	 */
741 	for (i = 0; i < 2; i++) {
742 		static struct {
743 			int data;
744 			int addr;
745 		} statregs[] = {
746 			{AC97_STAT_DATA1, AC97_STAT_ADDR1},
747 			{AC97_STAT_DATA2, AC97_STAT_ADDR2},
748 		};
749 
750 		if (i == 1 && ac97_id2 == -1)
751 			break;		/* secondary ac97 not available */
752 
753 		codec = &sc->sc_codec[i];
754 		memcpy(&codec->sc_dev, &sc->sc_dev, sizeof(codec->sc_dev));
755 		codec->sc = sc;
756 		codec->id = i == 1 ? ac97_id2 : 0;
757 		codec->status_data = statregs[i].data;
758 		codec->status_addr = statregs[i].addr;
759 		codec->host_if.arg = codec;
760 		codec->host_if.attach = yds_attach_codec;
761 		codec->host_if.read = yds_read_codec;
762 		codec->host_if.write = yds_write_codec;
763 		codec->host_if.reset = yds_reset_codec;
764 
765 		if ((r = ac97_attach(&codec->host_if)) != 0) {
766 			printf("%s: can't attach codec (error 0x%X)\n",
767 				sc->sc_dev.dv_xname, r);
768 			return;
769 		}
770 	}
771 
772 	/* Just enable the DAC and master volumes by default */
773 	ctl.type = AUDIO_MIXER_ENUM;
774 	ctl.un.ord = 0;  /* off */
775 	ctl.dev = yds_get_portnum_by_name(sc, AudioCoutputs,
776 	       AudioNmaster, AudioNmute);
777 	yds_mixer_set_port(sc, &ctl);
778 	ctl.dev = yds_get_portnum_by_name(sc, AudioCinputs,
779 	       AudioNdac, AudioNmute);
780 	yds_mixer_set_port(sc, &ctl);
781 	ctl.dev = yds_get_portnum_by_name(sc, AudioCinputs,
782 	       AudioNcd, AudioNmute);
783 	yds_mixer_set_port(sc, &ctl);
784 	ctl.dev = yds_get_portnum_by_name(sc, AudioCrecord,
785 	       AudioNvolume, AudioNmute);
786 	yds_mixer_set_port(sc, &ctl);
787 
788 	ctl.dev = yds_get_portnum_by_name(sc, AudioCrecord,
789 	       AudioNsource, NULL);
790 	ctl.type = AUDIO_MIXER_ENUM;
791 	ctl.un.ord = 0;
792 	yds_mixer_set_port(sc, &ctl);
793 
794 	/* Set a reasonable default volume */
795 	ctl.type = AUDIO_MIXER_VALUE;
796 	ctl.un.value.num_channels = 2;
797 	ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
798 	ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 127;
799 
800 	ctl.dev = sc->sc_codec[0].codec_if->vtbl->get_portnum_by_name(
801 		sc->sc_codec[0].codec_if, AudioCoutputs, AudioNmaster, NULL);
802 	yds_mixer_set_port(sc, &ctl);
803 
804 	audio_attach_mi(&yds_hw_if, sc, &sc->sc_dev);
805 
806 	/* Watch for power changes */
807 	sc->suspend = DVACT_RESUME;
808 	yds_configure_legacy(sc);
809 }
810 
811 int
812 yds_attach_codec(void *sc_, struct ac97_codec_if *codec_if)
813 {
814 	struct yds_codec_softc *sc = sc_;
815 
816 	sc->codec_if = codec_if;
817 	return 0;
818 }
819 
820 static int
821 yds_ready_codec(struct yds_codec_softc *sc)
822 {
823 	int to;
824 
825 	for (to = 0; to < AC97_TIMEOUT; to++) {
826 		if ((YREAD2(sc->sc, sc->status_addr) & AC97_BUSY) == 0)
827 			return 0;
828 		delay(1);
829 	}
830 
831 	return 1;
832 }
833 
834 int
835 yds_read_codec(void *sc_, u_int8_t reg, u_int16_t *data)
836 {
837 	struct yds_codec_softc *sc = sc_;
838 
839 	YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_READ | AC97_ID(sc->id) | reg);
840 
841 	if (yds_ready_codec(sc)) {
842 		printf("%s: yds_read_codec timeout\n",
843 		       sc->sc->sc_dev.dv_xname);
844 		return EIO;
845 	}
846 
847 	if (PCI_PRODUCT(sc->sc->sc_id) == PCI_PRODUCT_YAMAHA_YMF744 &&
848 	    sc->sc->sc_revision < 2) {
849 		int i;
850 
851 		for (i = 0; i < 600; i++)
852 			YREAD2(sc->sc, sc->status_data);
853 	}
854 	*data = YREAD2(sc->sc, sc->status_data);
855 
856 	return 0;
857 }
858 
859 int
860 yds_write_codec(void *sc_, u_int8_t reg, u_int16_t data)
861 {
862 	struct yds_codec_softc *sc = sc_;
863 
864 	YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_WRITE | AC97_ID(sc->id) | reg);
865 	YWRITE2(sc->sc, AC97_CMD_DATA, data);
866 
867 	if (yds_ready_codec(sc)) {
868 		printf("%s: yds_write_codec timeout\n",
869 			sc->sc->sc_dev.dv_xname);
870 		return EIO;
871 	}
872 
873 	return 0;
874 }
875 
876 /*
877  * XXX: Must handle the secondary differntly!!
878  */
879 void
880 yds_reset_codec(void *sc_)
881 {
882 	struct yds_codec_softc *codec = sc_;
883 	struct yds_softc *sc = codec->sc;
884 	pcireg_t reg;
885 
886 	/* reset AC97 codec */
887 	reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_DSCTRL);
888 	if (reg & 0x03) {
889 		pci_conf_write(sc->sc_pc, sc->sc_pcitag,
890 			       YDS_PCI_DSCTRL, reg & ~0x03);
891 		pci_conf_write(sc->sc_pc, sc->sc_pcitag,
892 			       YDS_PCI_DSCTRL, reg | 0x03);
893 		pci_conf_write(sc->sc_pc, sc->sc_pcitag,
894 			       YDS_PCI_DSCTRL, reg & ~0x03);
895 		delay(50000);
896 	}
897 
898 	yds_ready_codec(sc_);
899 }
900 
901 int
902 yds_intr(void *p)
903 {
904 	struct yds_softc *sc = p;
905 	u_int status;
906 
907 	mtx_enter(&audio_lock);
908 	status = YREAD4(sc, YDS_STATUS);
909 	DPRINTFN(1, ("yds_intr: status=%08x\n", status));
910 	if ((status & (YDS_STAT_INT|YDS_STAT_TINT)) == 0) {
911 #if 0
912 		if (sc->sc_mpu)
913 			return mpu_intr(sc->sc_mpu);
914 #endif
915 		mtx_leave(&audio_lock);
916 		return 0;
917 	}
918 
919 	if (status & YDS_STAT_TINT) {
920 		YWRITE4(sc, YDS_STATUS, YDS_STAT_TINT);
921 		printf ("yds_intr: timeout!\n");
922 	}
923 
924 	if (status & YDS_STAT_INT) {
925 		int nbank = (YREAD4(sc, YDS_CONTROL_SELECT) == 0);
926 
927 		/* Clear interrupt flag */
928 		YWRITE4(sc, YDS_STATUS, YDS_STAT_INT);
929 
930 		/* Buffer for the next frame is always ready. */
931 		YWRITE4(sc, YDS_MODE, YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV2);
932 
933 		if (sc->sc_play.intr) {
934 			u_int dma, cpu, blk, len;
935 
936 			/* Sync play slot control data */
937 			bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
938 					sc->pbankoff,
939 					sizeof(struct play_slot_ctrl_bank)*
940 					    (*sc->ptbl)*
941 					    N_PLAY_SLOT_CTRL_BANK,
942 					BUS_DMASYNC_POSTWRITE|
943 					BUS_DMASYNC_POSTREAD);
944 			dma = sc->pbankp[nbank]->pgstart;
945 			cpu = sc->sc_play.offset;
946 			blk = sc->sc_play.blksize;
947 			len = sc->sc_play.length;
948 
949 			if (((dma > cpu) && (dma - cpu > blk * 2)) ||
950 			    ((cpu > dma) && (dma + len - cpu > blk * 2))) {
951 				/* We can fill the next block */
952 				/* Sync ring buffer for previous write */
953 				bus_dmamap_sync(sc->sc_dmatag,
954 						sc->sc_play.dma->map,
955 						cpu, blk,
956 						BUS_DMASYNC_POSTWRITE);
957 				sc->sc_play.intr(sc->sc_play.intr_arg);
958 				sc->sc_play.offset += blk;
959 				if (sc->sc_play.offset >= len) {
960 					sc->sc_play.offset -= len;
961 #ifdef DIAGNOSTIC
962 					if (sc->sc_play.offset != 0)
963 						printf ("Audio ringbuffer botch\n");
964 #endif
965 				}
966 				/* Sync ring buffer for next write */
967 				bus_dmamap_sync(sc->sc_dmatag,
968 						sc->sc_play.dma->map,
969 						cpu, blk,
970 						BUS_DMASYNC_PREWRITE);
971 			}
972 		}
973 		if (sc->sc_rec.intr) {
974 			u_int dma, cpu, blk, len;
975 
976 			/* Sync rec slot control data */
977 			bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
978 					sc->rbankoff,
979 					sizeof(struct rec_slot_ctrl_bank)*
980 					    N_REC_SLOT_CTRL*
981 					    N_REC_SLOT_CTRL_BANK,
982 					BUS_DMASYNC_POSTWRITE|
983 					BUS_DMASYNC_POSTREAD);
984 			dma = sc->rbank[YDS_INPUT_SLOT*2 + nbank].pgstartadr;
985 			cpu = sc->sc_rec.offset;
986 			blk = sc->sc_rec.blksize;
987 			len = sc->sc_rec.length;
988 
989 			if (((dma > cpu) && (dma - cpu > blk * 2)) ||
990 			    ((cpu > dma) && (dma + len - cpu > blk * 2))) {
991 				/* We can drain the current block */
992 				/* Sync ring buffer first */
993 				bus_dmamap_sync(sc->sc_dmatag,
994 						sc->sc_rec.dma->map,
995 						cpu, blk,
996 						BUS_DMASYNC_POSTREAD);
997 				sc->sc_rec.intr(sc->sc_rec.intr_arg);
998 				sc->sc_rec.offset += blk;
999 				if (sc->sc_rec.offset >= len) {
1000 					sc->sc_rec.offset -= len;
1001 #ifdef DIAGNOSTIC
1002 					if (sc->sc_rec.offset != 0)
1003 						printf ("Audio ringbuffer botch\n");
1004 #endif
1005 				}
1006 				/* Sync ring buffer for next read */
1007 				bus_dmamap_sync(sc->sc_dmatag,
1008 						sc->sc_rec.dma->map,
1009 						cpu, blk,
1010 						BUS_DMASYNC_PREREAD);
1011 			}
1012 		}
1013 	}
1014 	mtx_leave(&audio_lock);
1015 	return 1;
1016 }
1017 
1018 int
1019 yds_allocmem(struct yds_softc *sc, size_t size, size_t align, struct yds_dma *p)
1020 {
1021 	int error;
1022 
1023 	p->size = size;
1024 	error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0,
1025 				 p->segs, nitems(p->segs),
1026 				 &p->nsegs, BUS_DMA_NOWAIT);
1027 	if (error)
1028 		return (error);
1029 
1030 	error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size,
1031 			       &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
1032 	if (error)
1033 		goto free;
1034 
1035 	error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,
1036 				  0, BUS_DMA_NOWAIT, &p->map);
1037 	if (error)
1038 		goto unmap;
1039 
1040 	error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL,
1041 				BUS_DMA_NOWAIT);
1042 	if (error)
1043 		goto destroy;
1044 	return (0);
1045 
1046 destroy:
1047 	bus_dmamap_destroy(sc->sc_dmatag, p->map);
1048 unmap:
1049 	bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
1050 free:
1051 	bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
1052 	return (error);
1053 }
1054 
1055 int
1056 yds_freemem(struct yds_softc *sc, struct yds_dma *p)
1057 {
1058 	bus_dmamap_unload(sc->sc_dmatag, p->map);
1059 	bus_dmamap_destroy(sc->sc_dmatag, p->map);
1060 	bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
1061 	bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
1062 	return 0;
1063 }
1064 
1065 int
1066 yds_open(void *addr, int flags)
1067 {
1068 	struct yds_softc *sc = addr;
1069 	int mode;
1070 
1071 	/* Select bank 0. */
1072 	YWRITE4(sc, YDS_CONTROL_SELECT, 0);
1073 
1074 	/* Start the DSP operation. */
1075 	mode = YREAD4(sc, YDS_MODE);
1076 	mode |= YDS_MODE_ACTV;
1077 	mode &= ~YDS_MODE_ACTV2;
1078 	YWRITE4(sc, YDS_MODE, mode);
1079 
1080 	return 0;
1081 }
1082 
1083 /*
1084  * Close function is called at splaudio().
1085  */
1086 void
1087 yds_close(void *addr)
1088 {
1089 	struct yds_softc *sc = addr;
1090 
1091 	yds_halt_output(sc);
1092 	yds_halt_input(sc);
1093 	yds_halt(sc);
1094 }
1095 
1096 int
1097 yds_query_encoding(void *addr, struct audio_encoding *fp)
1098 {
1099 	switch (fp->index) {
1100 	case 0:
1101 		strlcpy(fp->name, AudioEulinear, sizeof fp->name);
1102 		fp->encoding = AUDIO_ENCODING_ULINEAR;
1103 		fp->precision = 8;
1104 		fp->flags = 0;
1105 		break;
1106 	case 1:
1107 		strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
1108 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
1109 		fp->precision = 16;
1110 		fp->flags = 0;
1111 		break;
1112 	default:
1113 		return (EINVAL);
1114 	}
1115 	fp->bps = AUDIO_BPS(fp->precision);
1116 	fp->msb = 1;
1117 
1118 	return (0);
1119 }
1120 
1121 void
1122 yds_get_default_params(void *addr, int mode, struct audio_params *params)
1123 {
1124 	ac97_get_default_params(params);
1125 }
1126 
1127 int
1128 yds_set_params(void *addr, int setmode, int usemode,
1129     struct audio_params *play, struct audio_params *rec)
1130 {
1131 	struct audio_params *p;
1132 	int mode;
1133 
1134 	for (mode = AUMODE_RECORD; mode != -1;
1135 	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
1136 		if ((setmode & mode) == 0)
1137 			continue;
1138 
1139 		p = mode == AUMODE_PLAY ? play : rec;
1140 
1141 		if (p->sample_rate < 4000)
1142 			p->sample_rate = 4000;
1143 		if (p->sample_rate > 48000)
1144 			p->sample_rate = 48000;
1145 		if (p->precision > 16)
1146 			p->precision = 16;
1147 		if (p->channels > 2)
1148 			p->channels = 2;
1149 
1150 		switch (p->encoding) {
1151 		case AUDIO_ENCODING_SLINEAR_LE:
1152 			if (p->precision != 16)
1153 				return EINVAL;
1154 			break;
1155 		case AUDIO_ENCODING_ULINEAR_LE:
1156 		case AUDIO_ENCODING_ULINEAR_BE:
1157 			if (p->precision != 8)
1158 				return EINVAL;
1159 			break;
1160 		default:
1161 			return (EINVAL);
1162 		}
1163 		p->bps = AUDIO_BPS(p->precision);
1164 		p->msb = 1;
1165 	}
1166 
1167 	return 0;
1168 }
1169 
1170 int
1171 yds_round_blocksize(void *addr, int blk)
1172 {
1173 	/*
1174 	 * Block size must be bigger than a frame.
1175 	 * That is 1024bytes at most, i.e. for 48000Hz, 16bit, 2ch.
1176 	 */
1177 	if (blk < 1024)
1178 		blk = 1024;
1179 
1180 	return blk & ~4;
1181 }
1182 
1183 static u_int32_t
1184 yds_get_lpfq(u_int sample_rate)
1185 {
1186 	int i;
1187 	static struct lpfqt {
1188 		u_int rate;
1189 		u_int32_t lpfq;
1190 	} lpfqt[] = {
1191 		{8000,  0x32020000},
1192 		{11025, 0x31770000},
1193 		{16000, 0x31390000},
1194 		{22050, 0x31c90000},
1195 		{32000, 0x33d00000},
1196 		{48000, 0x40000000},
1197 		{0, 0}
1198 	};
1199 
1200 	if (sample_rate == 44100)		/* for P44 slot? */
1201 		return 0x370A0000;
1202 
1203 	for (i = 0; lpfqt[i].rate != 0; i++)
1204 		if (sample_rate <= lpfqt[i].rate)
1205 			break;
1206 
1207 	return lpfqt[i].lpfq;
1208 }
1209 
1210 static u_int32_t
1211 yds_get_lpfk(u_int sample_rate)
1212 {
1213 	int i;
1214 	static struct lpfkt {
1215 		u_int rate;
1216 		u_int32_t lpfk;
1217 	} lpfkt[] = {
1218 		{8000,  0x18b20000},
1219 		{11025, 0x20930000},
1220 		{16000, 0x2b9a0000},
1221 		{22050, 0x35a10000},
1222 		{32000, 0x3eaa0000},
1223 		{48000, 0x40000000},
1224 		{0, 0}
1225 	};
1226 
1227 	if (sample_rate == 44100)		/* for P44 slot? */
1228 		return 0x46460000;
1229 
1230 	for (i = 0; lpfkt[i].rate != 0; i++)
1231 		if (sample_rate <= lpfkt[i].rate)
1232 			break;
1233 
1234 	return lpfkt[i].lpfk;
1235 }
1236 
1237 int
1238 yds_trigger_output(void *addr, void *start, void *end, int blksize,
1239     void (*intr)(void *), void *arg, struct audio_params *param)
1240 #define P44		(sc->sc_flags & YDS_CAP_HAS_P44)
1241 {
1242 	struct yds_softc *sc = addr;
1243 	struct yds_dma *p;
1244 	struct play_slot_ctrl_bank *psb;
1245 	const u_int gain = 0x40000000;
1246 	bus_addr_t s;
1247 	size_t l;
1248 	int i;
1249 	int p44, channels;
1250 
1251 	mtx_enter(&audio_lock);
1252 #ifdef DIAGNOSTIC
1253 	if (sc->sc_play.intr)
1254 		panic("yds_trigger_output: already running");
1255 #endif
1256 	sc->sc_play.intr = intr;
1257 	sc->sc_play.intr_arg = arg;
1258 	sc->sc_play.offset = 0;
1259 	sc->sc_play.blksize = blksize;
1260 
1261 	DPRINTFN(1, ("yds_trigger_output: sc=%p start=%p end=%p "
1262 	    "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1263 
1264 	p = yds_find_dma(sc, start);
1265 	if (!p) {
1266 		printf("yds_trigger_output: bad addr %p\n", start);
1267 		mtx_leave(&audio_lock);
1268 		return (EINVAL);
1269 	}
1270 	sc->sc_play.dma = p;
1271 
1272 #ifdef DIAGNOSTIC
1273 	{
1274 		u_int32_t ctrlsize;
1275 		if ((ctrlsize = YREAD4(sc, YDS_PLAY_CTRLSIZE)) !=
1276 		    sizeof(struct play_slot_ctrl_bank) / sizeof(u_int32_t))
1277 			panic("%s: invalid play slot ctrldata %d %zd",
1278 			      sc->sc_dev.dv_xname, ctrlsize,
1279 			      sizeof(struct play_slot_ctrl_bank));
1280 	}
1281 #endif
1282 
1283 #ifdef YDS_USE_P44
1284 	/* The document says the P44 SRC supports only stereo, 16bit PCM. */
1285 	if (P44)
1286 		p44 = ((param->sample_rate == 44100) &&
1287 		       (param->channels == 2) &&
1288 		       (param->precision == 16));
1289 	else
1290 #endif
1291 		p44 = 0;
1292 	channels = p44 ? 1 : param->channels;
1293 
1294 	s = DMAADDR(p);
1295 	l = ((char *)end - (char *)start);
1296 	sc->sc_play.length = l;
1297 
1298 	*sc->ptbl = channels;	/* Num of play */
1299 
1300 	psb = sc->pbankp[0];
1301 	memset(psb, 0, sizeof(*psb));
1302 	psb->format = ((channels == 2 ? PSLT_FORMAT_STEREO : 0) |
1303 		       (param->precision == 8 ? PSLT_FORMAT_8BIT : 0) |
1304 		       (p44 ? PSLT_FORMAT_SRC441 : 0));
1305 	psb->pgbase = s;
1306 	psb->pgloopend = l;
1307 	if (!p44) {
1308 		psb->pgdeltaend = (param->sample_rate * 65536 / 48000) << 12;
1309 		psb->lpfkend = yds_get_lpfk(param->sample_rate);
1310 		psb->eggainend = gain;
1311 		psb->lpfq = yds_get_lpfq(param->sample_rate);
1312 		psb->pgdelta = psb->pgdeltaend;
1313 		psb->lpfk = yds_get_lpfk(param->sample_rate);
1314 		psb->eggain = gain;
1315 	}
1316 
1317 	for (i = 0; i < channels; i++) {
1318 		/* i == 0: left or mono, i == 1: right */
1319 		psb = sc->pbankp[i*2];
1320 		if (i)
1321 			/* copy from left */
1322 			*psb = *(sc->pbankp[0]);
1323 		if (channels == 2) {
1324 			/* stereo */
1325 			if (i == 0) {
1326 				psb->lchgain = psb->lchgainend = gain;
1327 			} else {
1328 				psb->lchgain = psb->lchgainend = 0;
1329 				psb->rchgain = psb->rchgainend = gain;
1330 				psb->format |= PSLT_FORMAT_RCH;
1331 			}
1332 		} else if (!p44) {
1333 			/* mono */
1334 			psb->lchgain = psb->rchgain = gain;
1335 			psb->lchgainend = psb->rchgainend = gain;
1336 		}
1337 		/* copy to the other bank */
1338 		*(sc->pbankp[i*2+1]) = *psb;
1339 	}
1340 
1341 	YDS_DUMP_PLAY_SLOT(5, sc, 0);
1342 	YDS_DUMP_PLAY_SLOT(5, sc, 1);
1343 
1344 	if (p44)
1345 		YWRITE4(sc, YDS_P44_OUT_VOLUME, 0x3fff3fff);
1346 	else
1347 		YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0x3fff3fff);
1348 
1349 	/* Now the play slot for the next frame is set up!! */
1350 	/* Sync play slot control data for both directions */
1351 	bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
1352 			sc->ptbloff,
1353 			sizeof(struct play_slot_ctrl_bank) *
1354 			    channels * N_PLAY_SLOT_CTRL_BANK,
1355 			BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
1356 	/* Sync ring buffer */
1357 	bus_dmamap_sync(sc->sc_dmatag, p->map, 0, blksize,
1358 			BUS_DMASYNC_PREWRITE);
1359 	/* HERE WE GO!! */
1360 	YWRITE4(sc, YDS_MODE,
1361 		YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2);
1362 	mtx_leave(&audio_lock);
1363 	return 0;
1364 }
1365 #undef P44
1366 
1367 int
1368 yds_trigger_input(void *addr, void *start, void *end, int blksize,
1369     void (*intr)(void *), void *arg, struct audio_params *param)
1370 {
1371 	struct yds_softc *sc = addr;
1372 	struct yds_dma *p;
1373 	u_int srate, format;
1374 	struct rec_slot_ctrl_bank *rsb;
1375 	bus_addr_t s;
1376 	size_t l;
1377 
1378 	mtx_enter(&audio_lock);
1379 #ifdef DIAGNOSTIC
1380 	if (sc->sc_rec.intr)
1381 		panic("yds_trigger_input: already running");
1382 #endif
1383 	sc->sc_rec.intr = intr;
1384 	sc->sc_rec.intr_arg = arg;
1385 	sc->sc_rec.offset = 0;
1386 	sc->sc_rec.blksize = blksize;
1387 
1388 	DPRINTFN(1, ("yds_trigger_input: "
1389 	    "sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1390 	    addr, start, end, blksize, intr, arg));
1391 	DPRINTFN(1, (" parameters: rate=%lu, precision=%u, channels=%u\n",
1392 	    param->sample_rate, param->precision, param->channels));
1393 
1394 	p = yds_find_dma(sc, start);
1395 	if (!p) {
1396 		printf("yds_trigger_input: bad addr %p\n", start);
1397 		mtx_leave(&audio_lock);
1398 		return (EINVAL);
1399 	}
1400 	sc->sc_rec.dma = p;
1401 
1402 	s = DMAADDR(p);
1403 	l = ((char *)end - (char *)start);
1404 	sc->sc_rec.length = l;
1405 
1406 	rsb = &sc->rbank[0];
1407 	memset(rsb, 0, sizeof(*rsb));
1408 	rsb->pgbase = s;
1409 	rsb->pgloopendadr = l;
1410 	/* Seems all 4 banks must be set up... */
1411 	sc->rbank[1] = *rsb;
1412 	sc->rbank[2] = *rsb;
1413 	sc->rbank[3] = *rsb;
1414 
1415 	YWRITE4(sc, YDS_ADC_IN_VOLUME, 0x3fff3fff);
1416 	YWRITE4(sc, YDS_REC_IN_VOLUME, 0x3fff3fff);
1417 	srate = 48000 * 4096 / param->sample_rate - 1;
1418 	format = ((param->precision == 8 ? YDS_FORMAT_8BIT : 0) |
1419 		  (param->channels == 2 ? YDS_FORMAT_STEREO : 0));
1420 	DPRINTF(("srate=%d, format=%08x\n", srate, format));
1421 #ifdef YDS_USE_REC_SLOT
1422 	YWRITE4(sc, YDS_DAC_REC_VOLUME, 0x3fff3fff);
1423 	YWRITE4(sc, YDS_P44_REC_VOLUME, 0x3fff3fff);
1424 	YWRITE4(sc, YDS_MAPOF_REC, YDS_RECSLOT_VALID);
1425 	YWRITE4(sc, YDS_REC_SAMPLE_RATE, srate);
1426 	YWRITE4(sc, YDS_REC_FORMAT, format);
1427 #else
1428 	YWRITE4(sc, YDS_MAPOF_REC, YDS_ADCSLOT_VALID);
1429 	YWRITE4(sc, YDS_ADC_SAMPLE_RATE, srate);
1430 	YWRITE4(sc, YDS_ADC_FORMAT, format);
1431 #endif
1432 	/* Now the rec slot for the next frame is set up!! */
1433 	/* Sync record slot control data */
1434 	bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
1435 			sc->rbankoff,
1436 			sizeof(struct rec_slot_ctrl_bank)*
1437 			    N_REC_SLOT_CTRL*
1438 			    N_REC_SLOT_CTRL_BANK,
1439 			BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
1440 	/* Sync ring buffer */
1441 	bus_dmamap_sync(sc->sc_dmatag, p->map, 0, blksize,
1442 			BUS_DMASYNC_PREREAD);
1443 	/* HERE WE GO!! */
1444 	YWRITE4(sc, YDS_MODE,
1445 		YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2);
1446 	mtx_leave(&audio_lock);
1447 	return 0;
1448 }
1449 
1450 static int
1451 yds_halt(struct yds_softc *sc)
1452 {
1453 	u_int32_t mode;
1454 
1455 	/* Stop the DSP operation. */
1456 	mode = YREAD4(sc, YDS_MODE);
1457 	YWRITE4(sc, YDS_MODE, mode & ~(YDS_MODE_ACTV|YDS_MODE_ACTV2));
1458 
1459 	/* Paranoia...  mute all */
1460 	YWRITE4(sc, YDS_P44_OUT_VOLUME, 0);
1461 	YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0);
1462 	YWRITE4(sc, YDS_ADC_IN_VOLUME, 0);
1463 	YWRITE4(sc, YDS_REC_IN_VOLUME, 0);
1464 	YWRITE4(sc, YDS_DAC_REC_VOLUME, 0);
1465 	YWRITE4(sc, YDS_P44_REC_VOLUME, 0);
1466 
1467 	return 0;
1468 }
1469 
1470 int
1471 yds_halt_output(void *addr)
1472 {
1473 	struct yds_softc *sc = addr;
1474 
1475 	DPRINTF(("yds: yds_halt_output\n"));
1476 	mtx_enter(&audio_lock);
1477 	if (sc->sc_play.intr) {
1478 		sc->sc_play.intr = 0;
1479 		/* Sync play slot control data */
1480 		bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
1481 				sc->pbankoff,
1482 				sizeof(struct play_slot_ctrl_bank)*
1483 				    (*sc->ptbl)*N_PLAY_SLOT_CTRL_BANK,
1484 				BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
1485 		/* Stop the play slot operation */
1486 		sc->pbankp[0]->status =
1487 		sc->pbankp[1]->status =
1488 		sc->pbankp[2]->status =
1489 		sc->pbankp[3]->status = 1;
1490 		/* Sync ring buffer */
1491 		bus_dmamap_sync(sc->sc_dmatag, sc->sc_play.dma->map,
1492 				0, sc->sc_play.length, BUS_DMASYNC_POSTWRITE);
1493 	}
1494 	mtx_leave(&audio_lock);
1495 	return 0;
1496 }
1497 
1498 int
1499 yds_halt_input(void *addr)
1500 {
1501 	struct yds_softc *sc = addr;
1502 
1503 	DPRINTF(("yds: yds_halt_input\n"));
1504 	mtx_enter(&audio_lock);
1505 	if (sc->sc_rec.intr) {
1506 		/* Stop the rec slot operation */
1507 		YWRITE4(sc, YDS_MAPOF_REC, 0);
1508 		sc->sc_rec.intr = 0;
1509 		/* Sync rec slot control data */
1510 		bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
1511 				sc->rbankoff,
1512 				sizeof(struct rec_slot_ctrl_bank)*
1513 				    N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK,
1514 				BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
1515 		/* Sync ring buffer */
1516 		bus_dmamap_sync(sc->sc_dmatag, sc->sc_rec.dma->map,
1517 				0, sc->sc_rec.length, BUS_DMASYNC_POSTREAD);
1518 	}
1519 	sc->sc_rec.intr = NULL;
1520 	mtx_leave(&audio_lock);
1521 	return 0;
1522 }
1523 
1524 int
1525 yds_getdev(void *addr, struct audio_device *retp)
1526 {
1527 	*retp = yds_device;
1528 
1529 	return 0;
1530 }
1531 
1532 int
1533 yds_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1534 {
1535 	struct yds_softc *sc = addr;
1536 
1537 	return (sc->sc_codec[0].codec_if->vtbl->mixer_set_port(
1538 	    sc->sc_codec[0].codec_if, cp));
1539 }
1540 
1541 int
1542 yds_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1543 {
1544 	struct yds_softc *sc = addr;
1545 
1546 	return (sc->sc_codec[0].codec_if->vtbl->mixer_get_port(
1547 	    sc->sc_codec[0].codec_if, cp));
1548 }
1549 
1550 int
1551 yds_query_devinfo(void *addr, mixer_devinfo_t *dip)
1552 {
1553 	struct yds_softc *sc = addr;
1554 
1555 	return (sc->sc_codec[0].codec_if->vtbl->query_devinfo(
1556 	    sc->sc_codec[0].codec_if, dip));
1557 }
1558 
1559 int
1560 yds_get_portnum_by_name(struct yds_softc *sc, char *class, char *device,
1561     char *qualifier)
1562 {
1563 	return (sc->sc_codec[0].codec_if->vtbl->get_portnum_by_name(
1564 	    sc->sc_codec[0].codec_if, class, device, qualifier));
1565 }
1566 
1567 void *
1568 yds_malloc(void *addr, int direction, size_t size, int pool, int flags)
1569 {
1570 	struct yds_softc *sc = addr;
1571 	struct yds_dma *p;
1572 	int error;
1573 
1574 	p = malloc(sizeof(*p), pool, flags);
1575 	if (!p)
1576 		return (0);
1577 	error = yds_allocmem(sc, size, 16, p);
1578 	if (error) {
1579 		free(p, pool, sizeof *p);
1580 		return (0);
1581 	}
1582 	p->next = sc->sc_dmas;
1583 	sc->sc_dmas = p;
1584 	return (KERNADDR(p));
1585 }
1586 
1587 void
1588 yds_free(void *addr, void *ptr, int pool)
1589 {
1590 	struct yds_softc *sc = addr;
1591 	struct yds_dma **pp, *p;
1592 
1593 	for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
1594 		if (KERNADDR(p) == ptr) {
1595 			yds_freemem(sc, p);
1596 			*pp = p->next;
1597 			free(p, pool, sizeof *p);
1598 			return;
1599 		}
1600 	}
1601 }
1602 
1603 static struct yds_dma *
1604 yds_find_dma(struct yds_softc *sc, void *addr)
1605 {
1606 	struct yds_dma *p;
1607 
1608 	for (p = sc->sc_dmas; p && KERNADDR(p) != addr; p = p->next)
1609 		;
1610 
1611 	return p;
1612 }
1613 
1614 size_t
1615 yds_round_buffersize(void *addr, int direction, size_t size)
1616 {
1617 	/*
1618 	 * Buffer size should be at least twice as bigger as a frame.
1619 	 */
1620 	if (size < 1024 * 3)
1621 		size = 1024 * 3;
1622 	return (size);
1623 }
1624 
1625 paddr_t
1626 yds_mappage(void *addr, void *mem, off_t off, int prot)
1627 {
1628 	struct yds_softc *sc = addr;
1629 	struct yds_dma *p;
1630 
1631 	if (off < 0)
1632 		return (-1);
1633 	p = yds_find_dma(sc, mem);
1634 	if (!p)
1635 		return (-1);
1636 	return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs,
1637 				off, prot, BUS_DMA_WAITOK));
1638 }
1639 
1640 int
1641 yds_get_props(void *addr)
1642 {
1643 	return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
1644 		AUDIO_PROP_FULLDUPLEX);
1645 }
1646 
1647 int
1648 yds_activate(struct device *self, int act)
1649 {
1650 	struct yds_softc *sc = (struct yds_softc *)self;
1651 	int rv = 0;
1652 
1653 	switch (act) {
1654 	case DVACT_QUIESCE:
1655 		if (sc->sc_play.intr || sc->sc_rec.intr)
1656 			sc->sc_resume_active = 1;
1657 		else
1658 			sc->sc_resume_active = 0;
1659 		rv = config_activate_children(self, act);
1660 		if (sc->sc_resume_active)
1661 			yds_close(sc);
1662 		break;
1663 	case DVACT_RESUME:
1664 		yds_halt(sc);
1665 		yds_init(sc, 1);
1666 		ac97_resume(&sc->sc_codec[0].host_if, sc->sc_codec[0].codec_if);
1667 		if (sc->sc_resume_active)
1668 			yds_open(sc, 0);
1669 		rv = config_activate_children(self, act);
1670 		break;
1671 	default:
1672 		rv = config_activate_children(self, act);
1673 		break;
1674 	}
1675 	return (rv);
1676 }
1677 
1678 int
1679 yds_init(struct yds_softc *sc, int resuming)
1680 {
1681 	u_int32_t reg;
1682 
1683 	pci_chipset_tag_t pc = sc->sc_pc;
1684 
1685 	int to;
1686 
1687 	DPRINTF(("in yds_init()\n"));
1688 
1689 	/* Download microcode */
1690 	if (!resuming) {
1691 		if (yds_download_mcode(sc)) {
1692 			printf("%s: download microcode failed\n", sc->sc_dev.dv_xname);
1693 			return -1;
1694 		}
1695 	}
1696 	/* Allocate DMA buffers */
1697 	if (yds_allocate_slots(sc, resuming)) {
1698 		printf("%s: could not allocate slots\n", sc->sc_dev.dv_xname);
1699 		return -1;
1700 	}
1701 
1702 	/* Warm reset */
1703 	reg = pci_conf_read(pc, sc->sc_pcitag, YDS_PCI_DSCTRL);
1704 	pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL, reg | YDS_DSCTRL_WRST);
1705 	delay(50000);
1706 
1707 	/*
1708 	 * Detect primary/secondary AC97
1709 	 *	YMF754 Hardware Specification Rev 1.01 page 24
1710 	 */
1711 	reg = pci_conf_read(pc, sc->sc_pcitag, YDS_PCI_DSCTRL);
1712 	pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL,
1713 		reg & ~YDS_DSCTRL_CRST);
1714 	delay(400000);		/* Needed for 740C. */
1715 
1716 	/* Primary */
1717 	for (to = 0; to < AC97_TIMEOUT; to++) {
1718 		if ((YREAD2(sc, AC97_STAT_ADDR1) & AC97_BUSY) == 0)
1719 			break;
1720 		delay(1);
1721 	}
1722 	if (to == AC97_TIMEOUT) {
1723 		printf("%s: no AC97 available\n", sc->sc_dev.dv_xname);
1724 		return -1;
1725 	}
1726 
1727 	/* Secondary */
1728 	/* Secondary AC97 is used for 4ch audio. Currently unused. */
1729 	ac97_id2 = -1;
1730 	if ((YREAD2(sc, YDS_ACTIVITY) & YDS_ACTIVITY_DOCKA) == 0)
1731 		goto detected;
1732 #if 0				/* reset secondary... */
1733 	YWRITE2(sc, YDS_GPIO_OCTRL,
1734 		YREAD2(sc, YDS_GPIO_OCTRL) & ~YDS_GPIO_GPO2);
1735 	YWRITE2(sc, YDS_GPIO_FUNCE,
1736 		(YREAD2(sc, YDS_GPIO_FUNCE)&(~YDS_GPIO_GPC2))|YDS_GPIO_GPE2);
1737 #endif
1738 	for (to = 0; to < AC97_TIMEOUT; to++) {
1739 		if ((YREAD2(sc, AC97_STAT_ADDR2) & AC97_BUSY) == 0)
1740 			break;
1741 		delay(1);
1742 	}
1743 	if (to < AC97_TIMEOUT) {
1744 		/* detect id */
1745 		for (ac97_id2 = 1; ac97_id2 < 4; ac97_id2++) {
1746 			YWRITE2(sc, AC97_CMD_ADDR,
1747 				AC97_CMD_READ | AC97_ID(ac97_id2) | 0x28);
1748 
1749 			for (to = 0; to < AC97_TIMEOUT; to++) {
1750 				if ((YREAD2(sc, AC97_STAT_ADDR2) & AC97_BUSY)
1751 				    == 0)
1752 					goto detected;
1753 				delay(1);
1754 			}
1755 		}
1756 		if (ac97_id2 == 4)
1757 			ac97_id2 = -1;
1758 detected:
1759 		;
1760 	}
1761 
1762 	pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL,
1763 		reg | YDS_DSCTRL_CRST);
1764 	delay (20);
1765 	pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL,
1766 		reg & ~YDS_DSCTRL_CRST);
1767 	delay (400000);
1768 	for (to = 0; to < AC97_TIMEOUT; to++) {
1769 		if ((YREAD2(sc, AC97_STAT_ADDR1) & AC97_BUSY) == 0)
1770 			break;
1771 		delay(1);
1772 	}
1773 
1774 	DPRINTF(("out of yds_init()\n"));
1775 
1776 	return 0;
1777 }
1778