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