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