This source file includes following definitions.
- eap_match
- eap1370_write_codec
- eap1371_ready_codec
- eap1371_read_codec
- eap1371_write_codec
- eap1371_src_wait
- eap1371_src_read
- eap1371_src_write
- eap1371_set_adc_rate
- eap1371_set_dac_rate
- eap_attach
- eap1371_attach_codec
- eap1371_reset_codec
- eap_intr
- eap_allocmem
- eap_freemem
- eap_open
- eap_close
- eap_query_encoding
- eap_set_params
- eap_round_blocksize
- eap_trigger_output
- eap_trigger_input
- eap_halt_output
- eap_halt_input
- eap_getdev
- eap1371_mixer_set_port
- eap1371_mixer_get_port
- eap1371_query_devinfo
- eap1371_get_portnum_by_name
- eap1370_set_mixer
- eap1370_mixer_set_port
- eap1370_mixer_get_port
- eap1370_query_devinfo
- eap_malloc
- eap_free
- eap_mappage
- eap_get_props
- eap_flags_codec
- eap_midi_open
- eap_midi_close
- eap_midi_output
- eap_midi_getinfo
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 #include "midi.h"
58
59 #include <sys/param.h>
60 #include <sys/systm.h>
61 #include <sys/kernel.h>
62 #include <sys/fcntl.h>
63 #include <sys/malloc.h>
64 #include <sys/device.h>
65 #include <sys/proc.h>
66
67 #include <dev/pci/pcidevs.h>
68 #include <dev/pci/pcivar.h>
69
70 #include <sys/audioio.h>
71 #include <dev/audio_if.h>
72 #include <dev/midi_if.h>
73 #include <dev/mulaw.h>
74 #include <dev/auconv.h>
75 #include <dev/ic/ac97.h>
76
77 #include <machine/bus.h>
78
79 #include <dev/pci/eapreg.h>
80
81 struct cfdriver eap_cd = {
82 NULL, "eap", DV_DULL
83 };
84
85 #define PCI_CBIO 0x10
86
87
88 #ifdef AUDIO_DEBUG
89 #define DPRINTF(x) if (eapdebug) printf x
90 #define DPRINTFN(n,x) if (eapdebug>(n)) printf x
91 int eapdebug = 20;
92 #else
93 #define DPRINTF(x)
94 #define DPRINTFN(n,x)
95 #endif
96
97 int eap_match(struct device *, void *, void *);
98 void eap_attach(struct device *, struct device *, void *);
99 int eap_intr(void *);
100
101 struct eap_dma {
102 bus_dmamap_t map;
103 caddr_t addr;
104 bus_dma_segment_t segs[1];
105 int nsegs;
106 size_t size;
107 struct eap_dma *next;
108 };
109
110 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
111 #define KERNADDR(p) ((void *)((p)->addr))
112
113 struct eap_softc {
114 struct device sc_dev;
115 void *sc_ih;
116 bus_space_tag_t iot;
117 bus_space_handle_t ioh;
118 bus_dma_tag_t sc_dmatag;
119
120 struct eap_dma *sc_dmas;
121
122 void (*sc_pintr)(void *);
123 void *sc_parg;
124 #ifdef DIAGNOSTIC
125 char sc_prun;
126 #endif
127
128 void (*sc_rintr)(void *);
129 void *sc_rarg;
130 #ifdef DIAGNOSTIC
131 char sc_rrun;
132 #endif
133
134 #if NMIDI > 0
135 void (*sc_iintr)(void *, int);
136 void (*sc_ointr)(void *);
137 void *sc_arg;
138 struct device *sc_mididev;
139 #endif
140
141 u_short sc_port[AK_NPORTS];
142 u_int sc_record_source;
143 u_int sc_output_source;
144 u_int sc_mic_preamp;
145 char sc_1371;
146
147 struct ac97_codec_if *codec_if;
148 struct ac97_host_if host_if;
149
150 int flags;
151 };
152
153 enum ac97_host_flags eap_flags_codec(void *);
154 int eap_allocmem(struct eap_softc *, size_t, size_t, struct eap_dma *);
155 int eap_freemem(struct eap_softc *, struct eap_dma *);
156
157 #define EWRITE1(sc, r, x) bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x))
158 #define EWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
159 #define EWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
160 #define EREAD1(sc, r) bus_space_read_1((sc)->iot, (sc)->ioh, (r))
161 #define EREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
162 #define EREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
163
164 struct cfattach eap_ca = {
165 sizeof(struct eap_softc), eap_match, eap_attach
166 };
167
168 int eap_open(void *, int);
169 void eap_close(void *);
170 int eap_query_encoding(void *, struct audio_encoding *);
171 int eap_set_params(void *, int, int, struct audio_params *, struct audio_params *);
172 int eap_round_blocksize(void *, int);
173 int eap_trigger_output(void *, void *, void *, int, void (*)(void *),
174 void *, struct audio_params *);
175 int eap_trigger_input(void *, void *, void *, int, void (*)(void *),
176 void *, struct audio_params *);
177 int eap_halt_output(void *);
178 int eap_halt_input(void *);
179 void eap1370_write_codec(struct eap_softc *, int, int);
180 int eap_getdev(void *, struct audio_device *);
181 int eap1370_mixer_set_port(void *, mixer_ctrl_t *);
182 int eap1370_mixer_get_port(void *, mixer_ctrl_t *);
183 int eap1371_mixer_set_port(void *, mixer_ctrl_t *);
184 int eap1371_mixer_get_port(void *, mixer_ctrl_t *);
185 int eap1370_query_devinfo(void *, mixer_devinfo_t *);
186 void *eap_malloc(void *, int, size_t, int, int);
187 void eap_free(void *, void *, int);
188 paddr_t eap_mappage(void *, void *, off_t, int);
189 int eap_get_props(void *);
190 void eap1370_set_mixer(struct eap_softc *sc, int a, int d);
191 u_int32_t eap1371_src_wait(struct eap_softc *sc);
192 void eap1371_set_adc_rate(struct eap_softc *sc, int rate);
193 void eap1371_set_dac_rate(struct eap_softc *sc, int rate, int which);
194 int eap1371_src_read(struct eap_softc *sc, int a);
195 void eap1371_src_write(struct eap_softc *sc, int a, int d);
196 int eap1371_query_devinfo(void *addr, mixer_devinfo_t *dip);
197
198 int eap1371_attach_codec(void *sc, struct ac97_codec_if *);
199 int eap1371_read_codec(void *sc, u_int8_t a, u_int16_t *d);
200 int eap1371_write_codec(void *sc, u_int8_t a, u_int16_t d);
201 void eap1371_reset_codec(void *sc);
202 int eap1371_get_portnum_by_name(struct eap_softc *, char *, char *,
203 char *);
204 #if NMIDI > 0
205 void eap_midi_close(void *);
206 void eap_midi_getinfo(void *, struct midi_info *);
207 int eap_midi_open(void *, int, void (*)(void *, int),
208 void (*)(void *), void *);
209 int eap_midi_output(void *, int);
210 #endif
211
212 struct audio_hw_if eap1370_hw_if = {
213 eap_open,
214 eap_close,
215 NULL,
216 eap_query_encoding,
217 eap_set_params,
218 eap_round_blocksize,
219 NULL,
220 NULL,
221 NULL,
222 NULL,
223 NULL,
224 eap_halt_output,
225 eap_halt_input,
226 NULL,
227 eap_getdev,
228 NULL,
229 eap1370_mixer_set_port,
230 eap1370_mixer_get_port,
231 eap1370_query_devinfo,
232 eap_malloc,
233 eap_free,
234 NULL,
235 eap_mappage,
236 eap_get_props,
237 eap_trigger_output,
238 eap_trigger_input,
239 };
240
241 struct audio_hw_if eap1371_hw_if = {
242 eap_open,
243 eap_close,
244 NULL,
245 eap_query_encoding,
246 eap_set_params,
247 eap_round_blocksize,
248 NULL,
249 NULL,
250 NULL,
251 NULL,
252 NULL,
253 eap_halt_output,
254 eap_halt_input,
255 NULL,
256 eap_getdev,
257 NULL,
258 eap1371_mixer_set_port,
259 eap1371_mixer_get_port,
260 eap1371_query_devinfo,
261 eap_malloc,
262 eap_free,
263 NULL,
264 eap_mappage,
265 eap_get_props,
266 eap_trigger_output,
267 eap_trigger_input,
268 };
269
270 #if NMIDI > 0
271 struct midi_hw_if eap_midi_hw_if = {
272 eap_midi_open,
273 eap_midi_close,
274 eap_midi_output,
275 0,
276 eap_midi_getinfo,
277 0,
278 };
279 #endif
280
281 struct audio_device eap_device = {
282 "Ensoniq AudioPCI",
283 "",
284 "eap"
285 };
286
287 const struct pci_matchid eap_devices[] = {
288 { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_EV1938 },
289 { PCI_VENDOR_ENSONIQ, PCI_PRODUCT_ENSONIQ_AUDIOPCI },
290 { PCI_VENDOR_ENSONIQ, PCI_PRODUCT_ENSONIQ_AUDIOPCI97 },
291 { PCI_VENDOR_ENSONIQ, PCI_PRODUCT_ENSONIQ_CT5880 },
292 };
293
294 int
295 eap_match(struct device *parent, void *match, void *aux)
296 {
297 return (pci_matchbyid((struct pci_attach_args *)aux, eap_devices,
298 sizeof(eap_devices)/sizeof(eap_devices[0])));
299 }
300
301 void
302 eap1370_write_codec(struct eap_softc *sc, int a, int d)
303 {
304 int icss, to;
305
306 to = EAP_WRITE_TIMEOUT;
307 do {
308 icss = EREAD4(sc, EAP_ICSS);
309 DPRINTFN(5,("eap: codec %d prog: icss=0x%08x\n", a, icss));
310 if (!to--) {
311 printf("%s: timeout writing to codec\n",
312 sc->sc_dev.dv_xname);
313 return;
314 }
315 } while (icss & EAP_CWRIP);
316 EWRITE4(sc, EAP_CODEC, EAP_SET_CODEC(a, d));
317 }
318
319
320
321
322
323
324 static __inline void
325 eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd)
326 {
327 int to, s;
328 u_int32_t src, t;
329
330 for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
331 if (!(EREAD4(sc, E1371_CODEC) & E1371_CODEC_WIP))
332 break;
333 delay(1);
334 }
335 if (to == EAP_WRITE_TIMEOUT)
336 printf("%s: eap1371_ready_codec timeout 1\n",
337 sc->sc_dev.dv_xname);
338
339 s = splaudio();
340 src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
341 EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK);
342
343 for (to = 0; to < EAP_READ_TIMEOUT; to++) {
344 t = EREAD4(sc, E1371_SRC);
345 if ((t & E1371_SRC_STATE_MASK) == 0)
346 break;
347 delay(1);
348 }
349 if (to == EAP_READ_TIMEOUT)
350 printf("%s: eap1371_ready_codec timeout 2\n",
351 sc->sc_dev.dv_xname);
352
353 for (to = 0; to < EAP_READ_TIMEOUT; to++) {
354 t = EREAD4(sc, E1371_SRC);
355 if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK)
356 break;
357 delay(1);
358 }
359 if (to == EAP_READ_TIMEOUT)
360 printf("%s: eap1371_ready_codec timeout 3\n",
361 sc->sc_dev.dv_xname);
362
363 EWRITE4(sc, E1371_CODEC, wd);
364
365 eap1371_src_wait(sc);
366 EWRITE4(sc, E1371_SRC, src);
367
368 splx(s);
369 }
370
371 int
372 eap1371_read_codec(void *sc_, u_int8_t a, u_int16_t *d)
373 {
374 struct eap_softc *sc = sc_;
375 int to;
376 u_int32_t t;
377
378 eap1371_ready_codec(sc, a, E1371_SET_CODEC(a, 0) | E1371_CODEC_READ);
379
380 for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
381 if (!(EREAD4(sc, E1371_CODEC) & E1371_CODEC_WIP))
382 break;
383 delay(1);
384 }
385 if (to == EAP_WRITE_TIMEOUT)
386 printf("%s: eap1371_read_codec timeout 1\n",
387 sc->sc_dev.dv_xname);
388
389 for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
390 t = EREAD4(sc, E1371_CODEC);
391 if (t & E1371_CODEC_VALID)
392 break;
393 delay(1);
394 }
395 if (to == EAP_WRITE_TIMEOUT)
396 printf("%s: eap1371_read_codec timeout 2\n",
397 sc->sc_dev.dv_xname);
398
399 *d = (u_int16_t)t;
400
401 DPRINTFN(10, ("eap1371: reading codec (%x) = %x\n", a, *d));
402
403 return (0);
404 }
405
406 int
407 eap1371_write_codec(void *sc_, u_int8_t a, u_int16_t d)
408 {
409 struct eap_softc *sc = sc_;
410
411 eap1371_ready_codec(sc, a, E1371_SET_CODEC(a, d));
412
413 DPRINTFN(10, ("eap1371: writing codec %x --> %x\n", d, a));
414
415 return (0);
416 }
417
418 u_int32_t
419 eap1371_src_wait(struct eap_softc *sc)
420 {
421 int to;
422 u_int32_t src;
423
424 for (to = 0; to < EAP_READ_TIMEOUT; to++) {
425 src = EREAD4(sc, E1371_SRC);
426 if (!(src & E1371_SRC_RBUSY))
427 return (src);
428 delay(1);
429 }
430 printf("%s: eap1371_src_wait timeout\n", sc->sc_dev.dv_xname);
431 return (src);
432 }
433
434 int
435 eap1371_src_read(struct eap_softc *sc, int a)
436 {
437 int to;
438 u_int32_t src, t;
439
440 src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
441 src |= E1371_SRC_ADDR(a);
442 EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK);
443
444 if ((eap1371_src_wait(sc) & E1371_SRC_STATE_MASK) != E1371_SRC_STATE_OK) {
445 for (to = 0; to < EAP_READ_TIMEOUT; to++) {
446 t = EREAD4(sc, E1371_SRC);
447 if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK)
448 break;
449 delay(1);
450 }
451 }
452
453 EWRITE4(sc, E1371_SRC, src);
454
455 return t & E1371_SRC_DATAMASK;
456 }
457
458 void
459 eap1371_src_write(struct eap_softc *sc, int a, int d)
460 {
461 u_int32_t r;
462
463 r = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
464 r |= E1371_SRC_RAMWE | E1371_SRC_ADDR(a) | E1371_SRC_DATA(d);
465 EWRITE4(sc, E1371_SRC, r);
466 }
467
468 void
469 eap1371_set_adc_rate(struct eap_softc *sc, int rate)
470 {
471 int freq, n, truncm;
472 int out;
473 int s;
474
475
476
477 if (rate > 48000)
478 rate = 48000;
479 if (rate < 4000)
480 rate = 4000;
481 n = rate / 3000;
482 if ((1 << n) & SRC_MAGIC)
483 n--;
484 truncm = ((21 * n) - 1) | 1;
485 freq = ((48000 << 15) / rate) * n;
486 if (rate >= 24000) {
487 if (truncm > 239)
488 truncm = 239;
489 out = ESRC_SET_TRUNC((239 - truncm) / 2);
490 } else {
491 if (truncm > 119)
492 truncm = 119;
493 out = ESRC_SMF | ESRC_SET_TRUNC((119 - truncm) / 2);
494 }
495 out |= ESRC_SET_N(n);
496 s = splaudio();
497 eap1371_src_write(sc, ESRC_ADC+ESRC_TRUNC_N, out);
498
499
500 out = eap1371_src_read(sc, ESRC_ADC+ESRC_IREGS) & 0xff;
501 eap1371_src_write(sc, ESRC_ADC+ESRC_IREGS, out |
502 ESRC_SET_VFI(freq >> 15));
503 eap1371_src_write(sc, ESRC_ADC+ESRC_VFF, freq & 0x7fff);
504 eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(n));
505 eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(n));
506 splx(s);
507 }
508
509 void
510 eap1371_set_dac_rate(struct eap_softc *sc, int rate, int which)
511 {
512 int dac = which == 1 ? ESRC_DAC1 : ESRC_DAC2;
513 int freq, r;
514 int s;
515
516
517
518 if (rate > 48000)
519 rate = 48000;
520 if (rate < 4000)
521 rate = 4000;
522 freq = ((rate << 15) + 1500) / 3000;
523
524 s = splaudio();
525 eap1371_src_wait(sc);
526 r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE |
527 E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC);
528 r |= (which == 1) ? E1371_SRC_DISP1 : E1371_SRC_DISP2;
529 EWRITE4(sc, E1371_SRC, r);
530 r = eap1371_src_read(sc, dac + ESRC_IREGS) & 0x00ff;
531 eap1371_src_write(sc, dac + ESRC_IREGS, r | ((freq >> 5) & 0xfc00));
532 eap1371_src_write(sc, dac + ESRC_VFF, freq & 0x7fff);
533 r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE |
534 E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC);
535 r &= ~(which == 1 ? E1371_SRC_DISP1 : E1371_SRC_DISP2);
536 EWRITE4(sc, E1371_SRC, r);
537 splx(s);
538 }
539
540 void
541 eap_attach(struct device *parent, struct device *self, void *aux)
542 {
543 struct eap_softc *sc = (struct eap_softc *)self;
544 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
545 pci_chipset_tag_t pc = pa->pa_pc;
546 struct audio_hw_if *eap_hw_if;
547 char const *intrstr;
548 pci_intr_handle_t ih;
549 mixer_ctrl_t ctl;
550 int i;
551 int revision, ct5880;
552
553
554 sc->sc_1371 = !(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ENSONIQ &&
555 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI);
556
557 revision = PCI_REVISION(pa->pa_class);
558 if (sc->sc_1371) {
559 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ENSONIQ &&
560 ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI97 &&
561 (revision == EAP_ES1373_8 || revision == EAP_CT5880_A)) ||
562 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_CT5880))
563 ct5880 = 1;
564 else
565 ct5880 = 0;
566 }
567
568
569 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
570 &sc->iot, &sc->ioh, NULL, NULL, 0)) {
571 return;
572 }
573
574 sc->sc_dmatag = pa->pa_dmat;
575
576
577 if (pci_intr_map(pa, &ih)) {
578 printf(": couldn't map interrupt\n");
579 return;
580 }
581 intrstr = pci_intr_string(pc, ih);
582 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, eap_intr, sc,
583 sc->sc_dev.dv_xname);
584 if (sc->sc_ih == NULL) {
585 printf(": couldn't establish interrupt");
586 if (intrstr != NULL)
587 printf(" at %s", intrstr);
588 printf("\n");
589 return;
590 }
591 printf(": %s\n", intrstr);
592
593 if (!sc->sc_1371) {
594
595
596 EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN);
597 EWRITE4(sc, EAP_ICSC, EAP_CDC_EN);
598
599
600
601
602 eap1370_write_codec(sc, AK_RESET, AK_PD);
603 eap1370_write_codec(sc, AK_RESET, AK_PD | AK_NRST);
604 eap1370_write_codec(sc, AK_CS, 0x0);
605
606 eap_hw_if = &eap1370_hw_if;
607
608
609 ctl.dev = EAP_OUTPUT_SELECT;
610 ctl.type = AUDIO_MIXER_SET;
611 ctl.un.mask = 1 << EAP_VOICE_VOL | 1 << EAP_FM_VOL |
612 1 << EAP_CD_VOL | 1 << EAP_LINE_VOL | 1 << EAP_AUX_VOL |
613 1 << EAP_MIC_VOL;
614 eap_hw_if->set_port(sc, &ctl);
615
616 ctl.type = AUDIO_MIXER_VALUE;
617 ctl.un.value.num_channels = 1;
618 for (ctl.dev = EAP_MASTER_VOL; ctl.dev < EAP_MIC_VOL;
619 ctl.dev++) {
620 ctl.un.value.level[AUDIO_MIXER_LEVEL_MONO] = VOL_0DB;
621 eap_hw_if->set_port(sc, &ctl);
622 }
623 ctl.un.value.level[AUDIO_MIXER_LEVEL_MONO] = 0;
624 eap_hw_if->set_port(sc, &ctl);
625 ctl.dev = EAP_MIC_PREAMP;
626 ctl.type = AUDIO_MIXER_ENUM;
627 ctl.un.ord = 0;
628 eap_hw_if->set_port(sc, &ctl);
629 ctl.dev = EAP_RECORD_SOURCE;
630 ctl.type = AUDIO_MIXER_SET;
631 ctl.un.mask = 1 << EAP_MIC_VOL;
632 eap_hw_if->set_port(sc, &ctl);
633 } else {
634
635
636 EWRITE4(sc, EAP_SIC, 0);
637 EWRITE4(sc, EAP_ICSC, 0);
638 EWRITE4(sc, E1371_LEGACY, 0);
639
640 if (ct5880) {
641 EWRITE4(sc, EAP_ICSS, EAP_CT5880_AC97_RESET);
642
643 delay(20000);
644 }
645
646
647 EWRITE4(sc, EAP_ICSC, E1371_SYNC_RES);
648 delay(20);
649 EWRITE4(sc, EAP_ICSC, 0);
650
651
652
653
654
655
656 EWRITE4(sc, E1371_SRC, E1371_SRC_DISABLE);
657 for (i = 0; i < 0x80; i++)
658 eap1371_src_write(sc, i, 0);
659 eap1371_src_write(sc, ESRC_DAC1+ESRC_TRUNC_N, ESRC_SET_N(16));
660 eap1371_src_write(sc, ESRC_DAC2+ESRC_TRUNC_N, ESRC_SET_N(16));
661 eap1371_src_write(sc, ESRC_DAC1+ESRC_IREGS, ESRC_SET_VFI(16));
662 eap1371_src_write(sc, ESRC_DAC2+ESRC_IREGS, ESRC_SET_VFI(16));
663 eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(16));
664 eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(16));
665 eap1371_src_write(sc, ESRC_DAC1_VOLL, ESRC_SET_DAC_VOLI(1));
666 eap1371_src_write(sc, ESRC_DAC1_VOLR, ESRC_SET_DAC_VOLI(1));
667 eap1371_src_write(sc, ESRC_DAC2_VOLL, ESRC_SET_DAC_VOLI(1));
668 eap1371_src_write(sc, ESRC_DAC2_VOLR, ESRC_SET_DAC_VOLI(1));
669 eap1371_set_adc_rate(sc, 22050);
670 eap1371_set_dac_rate(sc, 22050, 1);
671 eap1371_set_dac_rate(sc, 22050, 2);
672
673 EWRITE4(sc, E1371_SRC, 0);
674
675
676
677
678 sc->host_if.arg = sc;
679 sc->host_if.attach = eap1371_attach_codec;
680 sc->host_if.read = eap1371_read_codec;
681 sc->host_if.write = eap1371_write_codec;
682 sc->host_if.reset = eap1371_reset_codec;
683 sc->host_if.flags = eap_flags_codec;
684 sc->flags = AC97_HOST_DONT_READ;
685
686 if (ac97_attach(&sc->host_if) == 0) {
687
688 EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN);
689 } else
690 return;
691
692 eap_hw_if = &eap1371_hw_if;
693
694
695 ctl.type = AUDIO_MIXER_ENUM;
696 ctl.un.ord = 0;
697 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCoutputs,
698 AudioNmaster, AudioNmute);
699 eap1371_mixer_set_port(sc, &ctl);
700 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCinputs,
701 AudioNdac, AudioNmute);
702 eap1371_mixer_set_port(sc, &ctl);
703 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCrecord,
704 AudioNvolume, AudioNmute);
705 eap1371_mixer_set_port(sc, &ctl);
706
707 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCrecord,
708 AudioNsource, NULL);
709 ctl.type = AUDIO_MIXER_ENUM;
710 ctl.un.ord = 0;
711 eap1371_mixer_set_port(sc, &ctl);
712
713 }
714
715 audio_attach_mi(eap_hw_if, sc, &sc->sc_dev);
716 #if NMIDI > 0
717 sc->sc_mididev = midi_attach_mi(&eap_midi_hw_if, sc, &sc->sc_dev);
718 #endif
719 }
720
721 int
722 eap1371_attach_codec(void *sc_, struct ac97_codec_if *codec_if)
723 {
724 struct eap_softc *sc = sc_;
725
726 sc->codec_if = codec_if;
727 return (0);
728 }
729
730 void
731 eap1371_reset_codec(void *sc_)
732 {
733 struct eap_softc *sc = sc_;
734 u_int32_t icsc;
735 int s;
736
737 s = splaudio();
738 icsc = EREAD4(sc, EAP_ICSC);
739 EWRITE4(sc, EAP_ICSC, icsc | E1371_SYNC_RES);
740 delay(20);
741 EWRITE4(sc, EAP_ICSC, icsc & ~E1371_SYNC_RES);
742 delay(1);
743 splx(s);
744
745 return;
746 }
747
748 int
749 eap_intr(void *p)
750 {
751 struct eap_softc *sc = p;
752 u_int32_t intr, sic;
753
754 intr = EREAD4(sc, EAP_ICSS);
755 if (!(intr & EAP_INTR))
756 return (0);
757 sic = EREAD4(sc, EAP_SIC);
758 DPRINTFN(5, ("eap_intr: ICSS=0x%08x, SIC=0x%08x\n", intr, sic));
759 if (intr & EAP_I_ADC) {
760 #if 0
761
762
763
764
765
766
767
768 int s, nw, n;
769
770 EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
771 s = EREAD4(sc, EAP_ADC_CSR);
772 nw = ((s & 0xffff) + 1) >> 2;
773 n = 0;
774 while (((EREAD4(sc, EAP_ADC_SIZE) >> 16) + 8) % nw == 0) {
775 delay(10);
776 if (++n > 100) {
777 printf("eapintr: dma fix timeout");
778 break;
779 }
780 }
781
782 #endif
783 EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
784 EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN);
785 if (sc->sc_rintr)
786 sc->sc_rintr(sc->sc_rarg);
787 }
788 if (intr & EAP_I_DAC2) {
789 EWRITE4(sc, EAP_SIC, sic & ~EAP_P2_INTR_EN);
790 EWRITE4(sc, EAP_SIC, sic | EAP_P2_INTR_EN);
791 if (sc->sc_pintr)
792 sc->sc_pintr(sc->sc_parg);
793 }
794 #if NMIDI > 0
795 if ((intr & EAP_I_UART) && sc->sc_iintr != NULL) {
796 u_int32_t data;
797
798 if (EREAD1(sc, EAP_UART_STATUS) & EAP_US_RXINT) {
799 while (EREAD1(sc, EAP_UART_STATUS) & EAP_US_RXRDY) {
800 data = EREAD1(sc, EAP_UART_DATA);
801 sc->sc_iintr(sc->sc_arg, data);
802 }
803 }
804 }
805 #endif
806 return (1);
807 }
808
809 int
810 eap_allocmem(struct eap_softc *sc, size_t size, size_t align, struct eap_dma *p)
811 {
812 int error;
813
814 p->size = size;
815 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0,
816 p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
817 &p->nsegs, BUS_DMA_NOWAIT);
818 if (error)
819 return (error);
820
821 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size,
822 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
823 if (error)
824 goto free;
825
826 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,
827 0, BUS_DMA_NOWAIT, &p->map);
828 if (error)
829 goto unmap;
830
831 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL,
832 BUS_DMA_NOWAIT);
833 if (error)
834 goto destroy;
835 return (0);
836
837 destroy:
838 bus_dmamap_destroy(sc->sc_dmatag, p->map);
839 unmap:
840 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
841 free:
842 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
843 return (error);
844 }
845
846 int
847 eap_freemem(struct eap_softc *sc, struct eap_dma *p)
848 {
849 bus_dmamap_unload(sc->sc_dmatag, p->map);
850 bus_dmamap_destroy(sc->sc_dmatag, p->map);
851 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
852 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
853 return (0);
854 }
855
856 int
857 eap_open(void *addr, int flags)
858 {
859 return (0);
860 }
861
862
863
864
865 void
866 eap_close(void *addr)
867 {
868 struct eap_softc *sc = addr;
869
870 eap_halt_output(sc);
871 eap_halt_input(sc);
872
873 sc->sc_pintr = 0;
874 sc->sc_rintr = 0;
875 }
876
877 int
878 eap_query_encoding(void *addr, struct audio_encoding *fp)
879 {
880 switch (fp->index) {
881 case 0:
882 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
883 fp->encoding = AUDIO_ENCODING_ULINEAR;
884 fp->precision = 8;
885 fp->flags = 0;
886 return (0);
887 case 1:
888 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
889 fp->encoding = AUDIO_ENCODING_ULAW;
890 fp->precision = 8;
891 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
892 return (0);
893 case 2:
894 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
895 fp->encoding = AUDIO_ENCODING_ALAW;
896 fp->precision = 8;
897 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
898 return (0);
899 case 3:
900 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
901 fp->encoding = AUDIO_ENCODING_SLINEAR;
902 fp->precision = 8;
903 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
904 return (0);
905 case 4:
906 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
907 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
908 fp->precision = 16;
909 fp->flags = 0;
910 return (0);
911 case 5:
912 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
913 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
914 fp->precision = 16;
915 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
916 return (0);
917 case 6:
918 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
919 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
920 fp->precision = 16;
921 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
922 return (0);
923 case 7:
924 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
925 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
926 fp->precision = 16;
927 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
928 return (0);
929 default:
930 return (EINVAL);
931 }
932 }
933
934 int
935 eap_set_params(void *addr, int setmode, int usemode,
936 struct audio_params *play, struct audio_params *rec)
937 {
938 struct eap_softc *sc = addr;
939 struct audio_params *p;
940 int mode;
941 u_int32_t div;
942
943
944
945
946 if (!sc->sc_1371) {
947 if (play->sample_rate != rec->sample_rate &&
948 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
949 if (setmode == AUMODE_PLAY) {
950 rec->sample_rate = play->sample_rate;
951 setmode |= AUMODE_RECORD;
952 } else if (setmode == AUMODE_RECORD) {
953 play->sample_rate = rec->sample_rate;
954 setmode |= AUMODE_PLAY;
955 } else
956 return (EINVAL);
957 }
958 }
959
960 for (mode = AUMODE_RECORD; mode != -1;
961 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
962 if ((setmode & mode) == 0)
963 continue;
964
965 p = mode == AUMODE_PLAY ? play : rec;
966
967 if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
968 (p->precision != 8 && p->precision != 16) ||
969 (p->channels != 1 && p->channels != 2))
970 return (EINVAL);
971
972 p->factor = 1;
973 p->sw_code = 0;
974 switch (p->encoding) {
975 case AUDIO_ENCODING_SLINEAR_BE:
976 if (p->precision == 16)
977 p->sw_code = swap_bytes;
978 else
979 p->sw_code = change_sign8;
980 break;
981 case AUDIO_ENCODING_SLINEAR_LE:
982 if (p->precision != 16)
983 p->sw_code = change_sign8;
984 break;
985 case AUDIO_ENCODING_ULINEAR_BE:
986 if (p->precision == 16) {
987 if (mode == AUMODE_PLAY)
988 p->sw_code = swap_bytes_change_sign16_le;
989 else
990 p->sw_code = change_sign16_swap_bytes_le;
991 }
992 break;
993 case AUDIO_ENCODING_ULINEAR_LE:
994 if (p->precision == 16)
995 p->sw_code = change_sign16_le;
996 break;
997 case AUDIO_ENCODING_ULAW:
998 if (mode == AUMODE_PLAY) {
999 p->factor = 2;
1000 p->sw_code = mulaw_to_slinear16_le;
1001 } else
1002 p->sw_code = ulinear8_to_mulaw;
1003 break;
1004 case AUDIO_ENCODING_ALAW:
1005 if (mode == AUMODE_PLAY) {
1006 p->factor = 2;
1007 p->sw_code = alaw_to_slinear16_le;
1008 } else
1009 p->sw_code = ulinear8_to_alaw;
1010 break;
1011 default:
1012 return (EINVAL);
1013 }
1014 }
1015
1016 if (sc->sc_1371) {
1017 eap1371_set_dac_rate(sc, play->sample_rate, 1);
1018 eap1371_set_dac_rate(sc, play->sample_rate, 2);
1019 eap1371_set_adc_rate(sc, rec->sample_rate);
1020 } else {
1021
1022 DPRINTFN(2, ("eap_set_params: old ICSC = 0x%08x\n",
1023 EREAD4(sc, EAP_ICSC)));
1024 div = EREAD4(sc, EAP_ICSC) & ~EAP_PCLKBITS;
1025
1026
1027
1028
1029
1030
1031 if (usemode == AUMODE_RECORD)
1032 div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ /
1033 rec->sample_rate - 2);
1034 else
1035 div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ /
1036 play->sample_rate - 2);
1037 div |= EAP_CCB_INTRM;
1038 EWRITE4(sc, EAP_ICSC, div);
1039 DPRINTFN(2, ("eap_set_params: set ICSC = 0x%08x\n", div));
1040 }
1041
1042 return (0);
1043 }
1044
1045 int
1046 eap_round_blocksize(void *addr, int blk)
1047 {
1048 return ((blk + 31) & -32);
1049 }
1050
1051 int
1052 eap_trigger_output(
1053 void *addr,
1054 void *start,
1055 void *end,
1056 int blksize,
1057 void (*intr)(void *),
1058 void *arg,
1059 struct audio_params *param)
1060 {
1061 struct eap_softc *sc = addr;
1062 struct eap_dma *p;
1063 u_int32_t icsc, sic;
1064 int sampshift;
1065
1066 #ifdef DIAGNOSTIC
1067 if (sc->sc_prun)
1068 panic("eap_trigger_output: already running");
1069 sc->sc_prun = 1;
1070 #endif
1071
1072 DPRINTFN(1, ("eap_trigger_output: sc=%p start=%p end=%p "
1073 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1074 sc->sc_pintr = intr;
1075 sc->sc_parg = arg;
1076
1077 sic = EREAD4(sc, EAP_SIC);
1078 sic &= ~(EAP_P2_S_EB | EAP_P2_S_MB | EAP_INC_BITS);
1079 sic |= EAP_SET_P2_ST_INC(0) | EAP_SET_P2_END_INC(param->precision * param->factor / 8);
1080 sampshift = 0;
1081 if (param->precision * param->factor == 16) {
1082 sic |= EAP_P2_S_EB;
1083 sampshift++;
1084 }
1085 if (param->channels == 2) {
1086 sic |= EAP_P2_S_MB;
1087 sampshift++;
1088 }
1089 EWRITE4(sc, EAP_SIC, sic & ~EAP_P2_INTR_EN);
1090 EWRITE4(sc, EAP_SIC, sic | EAP_P2_INTR_EN);
1091
1092 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
1093 ;
1094 if (!p) {
1095 printf("eap_trigger_output: bad addr %p\n", start);
1096 return (EINVAL);
1097 }
1098
1099 DPRINTF(("eap_trigger_output: DAC2_ADDR=0x%x, DAC2_SIZE=0x%x\n",
1100 (int)DMAADDR(p),
1101 (int)EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)));
1102 EWRITE4(sc, EAP_MEMPAGE, EAP_DAC_PAGE);
1103 EWRITE4(sc, EAP_DAC2_ADDR, DMAADDR(p));
1104 EWRITE4(sc, EAP_DAC2_SIZE,
1105 EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1));
1106
1107 EWRITE4(sc, EAP_DAC2_CSR, (blksize >> sampshift) - 1);
1108
1109 if (sc->sc_1371)
1110 EWRITE4(sc, E1371_SRC, 0);
1111
1112 icsc = EREAD4(sc, EAP_ICSC);
1113 EWRITE4(sc, EAP_ICSC, icsc | EAP_DAC2_EN);
1114
1115 DPRINTFN(1, ("eap_trigger_output: set ICSC = 0x%08x\n", icsc));
1116
1117 return (0);
1118 }
1119
1120 int
1121 eap_trigger_input(
1122 void *addr,
1123 void *start,
1124 void *end,
1125 int blksize,
1126 void (*intr)(void *),
1127 void *arg,
1128 struct audio_params *param)
1129 {
1130 struct eap_softc *sc = addr;
1131 struct eap_dma *p;
1132 u_int32_t icsc, sic;
1133 int sampshift;
1134
1135 #ifdef DIAGNOSTIC
1136 if (sc->sc_rrun)
1137 panic("eap_trigger_input: already running");
1138 sc->sc_rrun = 1;
1139 #endif
1140
1141 DPRINTFN(1, ("eap_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1142 addr, start, end, blksize, intr, arg));
1143 sc->sc_rintr = intr;
1144 sc->sc_rarg = arg;
1145
1146 sic = EREAD4(sc, EAP_SIC);
1147 sic &= ~(EAP_R1_S_EB | EAP_R1_S_MB);
1148 sampshift = 0;
1149 if (param->precision * param->factor == 16) {
1150 sic |= EAP_R1_S_EB;
1151 sampshift++;
1152 }
1153 if (param->channels == 2) {
1154 sic |= EAP_R1_S_MB;
1155 sampshift++;
1156 }
1157 EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
1158 EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN);
1159
1160 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
1161 ;
1162 if (!p) {
1163 printf("eap_trigger_input: bad addr %p\n", start);
1164 return (EINVAL);
1165 }
1166
1167 DPRINTF(("eap_trigger_input: ADC_ADDR=0x%x, ADC_SIZE=0x%x\n",
1168 (int)DMAADDR(p),
1169 (int)EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)));
1170 EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
1171 EWRITE4(sc, EAP_ADC_ADDR, DMAADDR(p));
1172 EWRITE4(sc, EAP_ADC_SIZE,
1173 EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1));
1174
1175 EWRITE4(sc, EAP_ADC_CSR, (blksize >> sampshift) - 1);
1176
1177 if (sc->sc_1371)
1178 EWRITE4(sc, E1371_SRC, 0);
1179
1180 icsc = EREAD4(sc, EAP_ICSC);
1181 EWRITE4(sc, EAP_ICSC, icsc | EAP_ADC_EN);
1182
1183 DPRINTFN(1, ("eap_trigger_input: set ICSC = 0x%08x\n", icsc));
1184
1185 return (0);
1186 }
1187
1188 int
1189 eap_halt_output(void *addr)
1190 {
1191 struct eap_softc *sc = addr;
1192 u_int32_t icsc;
1193
1194 DPRINTF(("eap: eap_halt_output\n"));
1195 icsc = EREAD4(sc, EAP_ICSC);
1196 EWRITE4(sc, EAP_ICSC, icsc & ~EAP_DAC2_EN);
1197 #ifdef DIAGNOSTIC
1198 sc->sc_prun = 0;
1199 #endif
1200 return (0);
1201 }
1202
1203 int
1204 eap_halt_input(void *addr)
1205 {
1206 struct eap_softc *sc = addr;
1207 u_int32_t icsc;
1208
1209 DPRINTF(("eap: eap_halt_input\n"));
1210 icsc = EREAD4(sc, EAP_ICSC);
1211 EWRITE4(sc, EAP_ICSC, icsc & ~EAP_ADC_EN);
1212 #ifdef DIAGNOSTIC
1213 sc->sc_rrun = 0;
1214 #endif
1215 return (0);
1216 }
1217
1218 int
1219 eap_getdev(void *addr, struct audio_device *retp)
1220 {
1221 *retp = eap_device;
1222 return (0);
1223 }
1224
1225 int
1226 eap1371_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1227 {
1228 struct eap_softc *sc = addr;
1229
1230 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp));
1231 }
1232
1233 int
1234 eap1371_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1235 {
1236 struct eap_softc *sc = addr;
1237
1238 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp));
1239 }
1240
1241 int
1242 eap1371_query_devinfo(void *addr, mixer_devinfo_t *dip)
1243 {
1244 struct eap_softc *sc = addr;
1245
1246 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip));
1247 }
1248
1249 int
1250 eap1371_get_portnum_by_name(struct eap_softc *sc,
1251 char *class, char *device, char *qualifier)
1252 {
1253 return (sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, class,
1254 device, qualifier));
1255 }
1256
1257 void
1258 eap1370_set_mixer(struct eap_softc *sc, int a, int d)
1259 {
1260 eap1370_write_codec(sc, a, d);
1261
1262 sc->sc_port[a] = d;
1263 DPRINTFN(1, ("eap1370_mixer_set_port port 0x%02x = 0x%02x\n", a, d));
1264 }
1265
1266 int
1267 eap1370_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1268 {
1269 struct eap_softc *sc = addr;
1270 int lval, rval, l, r, la, ra;
1271 int l1, r1, l2, r2, m, o1, o2;
1272
1273 if (cp->dev == EAP_RECORD_SOURCE) {
1274 if (cp->type != AUDIO_MIXER_SET)
1275 return (EINVAL);
1276 m = sc->sc_record_source = cp->un.mask;
1277 l1 = l2 = r1 = r2 = 0;
1278 if (m & (1 << EAP_VOICE_VOL))
1279 l2 |= AK_M_VOICE, r2 |= AK_M_VOICE;
1280 if (m & (1 << EAP_FM_VOL))
1281 l1 |= AK_M_FM_L, r1 |= AK_M_FM_R;
1282 if (m & (1 << EAP_CD_VOL))
1283 l1 |= AK_M_CD_L, r1 |= AK_M_CD_R;
1284 if (m & (1 << EAP_LINE_VOL))
1285 l1 |= AK_M_LINE_L, r1 |= AK_M_LINE_R;
1286 if (m & (1 << EAP_AUX_VOL))
1287 l2 |= AK_M2_AUX_L, r2 |= AK_M2_AUX_R;
1288 if (m & (1 << EAP_MIC_VOL))
1289 l2 |= AK_M_TMIC, r2 |= AK_M_TMIC;
1290 eap1370_set_mixer(sc, AK_IN_MIXER1_L, l1);
1291 eap1370_set_mixer(sc, AK_IN_MIXER1_R, r1);
1292 eap1370_set_mixer(sc, AK_IN_MIXER2_L, l2);
1293 eap1370_set_mixer(sc, AK_IN_MIXER2_R, r2);
1294 return (0);
1295 }
1296 if (cp->dev == EAP_OUTPUT_SELECT) {
1297 if (cp->type != AUDIO_MIXER_SET)
1298 return (EINVAL);
1299 m = sc->sc_output_source = cp->un.mask;
1300 o1 = o2 = 0;
1301 if (m & (1 << EAP_VOICE_VOL))
1302 o2 |= AK_M_VOICE_L | AK_M_VOICE_R;
1303 if (m & (1 << EAP_FM_VOL))
1304 o1 |= AK_M_FM_L | AK_M_FM_R;
1305 if (m & (1 << EAP_CD_VOL))
1306 o1 |= AK_M_CD_L | AK_M_CD_R;
1307 if (m & (1 << EAP_LINE_VOL))
1308 o1 |= AK_M_LINE_L | AK_M_LINE_R;
1309 if (m & (1 << EAP_AUX_VOL))
1310 o2 |= AK_M_AUX_L | AK_M_AUX_R;
1311 if (m & (1 << EAP_MIC_VOL))
1312 o1 |= AK_M_MIC;
1313 eap1370_set_mixer(sc, AK_OUT_MIXER1, o1);
1314 eap1370_set_mixer(sc, AK_OUT_MIXER2, o2);
1315 return (0);
1316 }
1317 if (cp->dev == EAP_MIC_PREAMP) {
1318 if (cp->type != AUDIO_MIXER_ENUM)
1319 return (EINVAL);
1320 if (cp->un.ord != 0 && cp->un.ord != 1)
1321 return (EINVAL);
1322 sc->sc_mic_preamp = cp->un.ord;
1323 eap1370_set_mixer(sc, AK_MGAIN, cp->un.ord);
1324 return (0);
1325 }
1326 if (cp->type != AUDIO_MIXER_VALUE)
1327 return (EINVAL);
1328 if (cp->un.value.num_channels == 1)
1329 lval = rval = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
1330 else if (cp->un.value.num_channels == 2) {
1331 lval = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1332 rval = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1333 } else
1334 return (EINVAL);
1335 ra = -1;
1336 switch (cp->dev) {
1337 case EAP_MASTER_VOL:
1338 l = VOL_TO_ATT5(lval);
1339 r = VOL_TO_ATT5(rval);
1340 la = AK_MASTER_L;
1341 ra = AK_MASTER_R;
1342 break;
1343 case EAP_MIC_VOL:
1344 if (cp->un.value.num_channels != 1)
1345 return (EINVAL);
1346 la = AK_MIC;
1347 goto lr;
1348 case EAP_VOICE_VOL:
1349 la = AK_VOICE_L;
1350 ra = AK_VOICE_R;
1351 goto lr;
1352 case EAP_FM_VOL:
1353 la = AK_FM_L;
1354 ra = AK_FM_R;
1355 goto lr;
1356 case EAP_CD_VOL:
1357 la = AK_CD_L;
1358 ra = AK_CD_R;
1359 goto lr;
1360 case EAP_LINE_VOL:
1361 la = AK_LINE_L;
1362 ra = AK_LINE_R;
1363 goto lr;
1364 case EAP_AUX_VOL:
1365 la = AK_AUX_L;
1366 ra = AK_AUX_R;
1367 lr:
1368 l = VOL_TO_GAIN5(lval);
1369 r = VOL_TO_GAIN5(rval);
1370 break;
1371 default:
1372 return (EINVAL);
1373 }
1374 eap1370_set_mixer(sc, la, l);
1375 if (ra >= 0) {
1376 eap1370_set_mixer(sc, ra, r);
1377 }
1378 return (0);
1379 }
1380
1381 int
1382 eap1370_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1383 {
1384 struct eap_softc *sc = addr;
1385 int la, ra, l, r;
1386
1387 switch (cp->dev) {
1388 case EAP_RECORD_SOURCE:
1389 if (cp->type != AUDIO_MIXER_SET)
1390 return (EINVAL);
1391 cp->un.mask = sc->sc_record_source;
1392 return (0);
1393 case EAP_OUTPUT_SELECT:
1394 if (cp->type != AUDIO_MIXER_SET)
1395 return (EINVAL);
1396 cp->un.mask = sc->sc_output_source;
1397 return (0);
1398 case EAP_MIC_PREAMP:
1399 if (cp->type != AUDIO_MIXER_ENUM)
1400 return (EINVAL);
1401 cp->un.ord = sc->sc_mic_preamp;
1402 return (0);
1403 case EAP_MASTER_VOL:
1404 l = ATT5_TO_VOL(sc->sc_port[AK_MASTER_L]);
1405 r = ATT5_TO_VOL(sc->sc_port[AK_MASTER_R]);
1406 break;
1407 case EAP_MIC_VOL:
1408 if (cp->un.value.num_channels != 1)
1409 return (EINVAL);
1410 la = ra = AK_MIC;
1411 goto lr;
1412 case EAP_VOICE_VOL:
1413 la = AK_VOICE_L;
1414 ra = AK_VOICE_R;
1415 goto lr;
1416 case EAP_FM_VOL:
1417 la = AK_FM_L;
1418 ra = AK_FM_R;
1419 goto lr;
1420 case EAP_CD_VOL:
1421 la = AK_CD_L;
1422 ra = AK_CD_R;
1423 goto lr;
1424 case EAP_LINE_VOL:
1425 la = AK_LINE_L;
1426 ra = AK_LINE_R;
1427 goto lr;
1428 case EAP_AUX_VOL:
1429 la = AK_AUX_L;
1430 ra = AK_AUX_R;
1431 lr:
1432 l = GAIN5_TO_VOL(sc->sc_port[la]);
1433 r = GAIN5_TO_VOL(sc->sc_port[ra]);
1434 break;
1435 default:
1436 return (EINVAL);
1437 }
1438 if (cp->un.value.num_channels == 1)
1439 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r) / 2;
1440 else if (cp->un.value.num_channels == 2) {
1441 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
1442 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
1443 } else
1444 return (EINVAL);
1445 return (0);
1446 }
1447
1448 int
1449 eap1370_query_devinfo(void *addr, mixer_devinfo_t *dip)
1450 {
1451 switch (dip->index) {
1452 case EAP_MASTER_VOL:
1453 dip->type = AUDIO_MIXER_VALUE;
1454 dip->mixer_class = EAP_OUTPUT_CLASS;
1455 dip->prev = dip->next = AUDIO_MIXER_LAST;
1456 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
1457 dip->un.v.num_channels = 2;
1458 strlcpy(dip->un.v.units.name, AudioNvolume,
1459 sizeof dip->un.v.units.name);
1460 return (0);
1461 case EAP_VOICE_VOL:
1462 dip->type = AUDIO_MIXER_VALUE;
1463 dip->mixer_class = EAP_INPUT_CLASS;
1464 dip->prev = AUDIO_MIXER_LAST;
1465 dip->next = AUDIO_MIXER_LAST;
1466 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
1467 dip->un.v.num_channels = 2;
1468 strlcpy(dip->un.v.units.name, AudioNvolume,
1469 sizeof dip->un.v.units.name);
1470 return (0);
1471 case EAP_FM_VOL:
1472 dip->type = AUDIO_MIXER_VALUE;
1473 dip->mixer_class = EAP_INPUT_CLASS;
1474 dip->prev = AUDIO_MIXER_LAST;
1475 dip->next = AUDIO_MIXER_LAST;
1476 strlcpy(dip->label.name, AudioNfmsynth,
1477 sizeof dip->label.name);
1478 dip->un.v.num_channels = 2;
1479 strlcpy(dip->un.v.units.name, AudioNvolume,
1480 sizeof dip->un.v.units.name);
1481 return (0);
1482 case EAP_CD_VOL:
1483 dip->type = AUDIO_MIXER_VALUE;
1484 dip->mixer_class = EAP_INPUT_CLASS;
1485 dip->prev = AUDIO_MIXER_LAST;
1486 dip->next = AUDIO_MIXER_LAST;
1487 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
1488 dip->un.v.num_channels = 2;
1489 strlcpy(dip->un.v.units.name, AudioNvolume,
1490 sizeof dip->un.v.units.name);
1491 return (0);
1492 case EAP_LINE_VOL:
1493 dip->type = AUDIO_MIXER_VALUE;
1494 dip->mixer_class = EAP_INPUT_CLASS;
1495 dip->prev = AUDIO_MIXER_LAST;
1496 dip->next = AUDIO_MIXER_LAST;
1497 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
1498 dip->un.v.num_channels = 2;
1499 strlcpy(dip->un.v.units.name, AudioNvolume,
1500 sizeof dip->un.v.units.name);
1501 return (0);
1502 case EAP_AUX_VOL:
1503 dip->type = AUDIO_MIXER_VALUE;
1504 dip->mixer_class = EAP_INPUT_CLASS;
1505 dip->prev = AUDIO_MIXER_LAST;
1506 dip->next = AUDIO_MIXER_LAST;
1507 strlcpy(dip->label.name, AudioNaux, sizeof dip->label.name);
1508 dip->un.v.num_channels = 2;
1509 strlcpy(dip->un.v.units.name, AudioNvolume,
1510 sizeof dip->un.v.units.name);
1511 return (0);
1512 case EAP_MIC_VOL:
1513 dip->type = AUDIO_MIXER_VALUE;
1514 dip->mixer_class = EAP_INPUT_CLASS;
1515 dip->prev = AUDIO_MIXER_LAST;
1516 dip->next = EAP_MIC_PREAMP;
1517 strlcpy(dip->label.name, AudioNmicrophone,
1518 sizeof dip->label.name);
1519 dip->un.v.num_channels = 1;
1520 strlcpy(dip->un.v.units.name, AudioNvolume,
1521 sizeof dip->un.v.units.name);
1522 return (0);
1523 case EAP_RECORD_SOURCE:
1524 dip->mixer_class = EAP_RECORD_CLASS;
1525 dip->prev = dip->next = AUDIO_MIXER_LAST;
1526 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
1527 dip->type = AUDIO_MIXER_SET;
1528 dip->un.s.num_mem = 6;
1529 strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone,
1530 sizeof dip->un.s.member[0].label.name);
1531 dip->un.s.member[0].mask = 1 << EAP_MIC_VOL;
1532 strlcpy(dip->un.s.member[1].label.name, AudioNcd,
1533 sizeof dip->un.s.member[1].label.name);
1534 dip->un.s.member[1].mask = 1 << EAP_CD_VOL;
1535 strlcpy(dip->un.s.member[2].label.name, AudioNline,
1536 sizeof dip->un.s.member[2].label.name);
1537 dip->un.s.member[2].mask = 1 << EAP_LINE_VOL;
1538 strlcpy(dip->un.s.member[3].label.name, AudioNfmsynth,
1539 sizeof dip->un.s.member[3].label.name);
1540 dip->un.s.member[3].mask = 1 << EAP_FM_VOL;
1541 strlcpy(dip->un.s.member[4].label.name, AudioNaux,
1542 sizeof dip->un.s.member[4].label.name);
1543 dip->un.s.member[4].mask = 1 << EAP_AUX_VOL;
1544 strlcpy(dip->un.s.member[5].label.name, AudioNdac,
1545 sizeof dip->un.s.member[5].label.name);
1546 dip->un.s.member[5].mask = 1 << EAP_VOICE_VOL;
1547 return (0);
1548 case EAP_OUTPUT_SELECT:
1549 dip->mixer_class = EAP_OUTPUT_CLASS;
1550 dip->prev = dip->next = AUDIO_MIXER_LAST;
1551 strlcpy(dip->label.name, AudioNselect, sizeof dip->label.name);
1552 dip->type = AUDIO_MIXER_SET;
1553 dip->un.s.num_mem = 6;
1554 strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone,
1555 sizeof dip->un.s.member[0].label.name);
1556 dip->un.s.member[0].mask = 1 << EAP_MIC_VOL;
1557 strlcpy(dip->un.s.member[1].label.name, AudioNcd,
1558 sizeof dip->un.s.member[1].label.name);
1559 dip->un.s.member[1].mask = 1 << EAP_CD_VOL;
1560 strlcpy(dip->un.s.member[2].label.name, AudioNline,
1561 sizeof dip->un.s.member[2].label.name);
1562 dip->un.s.member[2].mask = 1 << EAP_LINE_VOL;
1563 strlcpy(dip->un.s.member[3].label.name, AudioNfmsynth,
1564 sizeof dip->un.s.member[3].label.name);
1565 dip->un.s.member[3].mask = 1 << EAP_FM_VOL;
1566 strlcpy(dip->un.s.member[4].label.name, AudioNaux,
1567 sizeof dip->un.s.member[4].label.name);
1568 dip->un.s.member[4].mask = 1 << EAP_AUX_VOL;
1569 strlcpy(dip->un.s.member[5].label.name, AudioNdac,
1570 sizeof dip->un.s.member[5].label.name);
1571 dip->un.s.member[5].mask = 1 << EAP_VOICE_VOL;
1572 return (0);
1573 case EAP_MIC_PREAMP:
1574 dip->type = AUDIO_MIXER_ENUM;
1575 dip->mixer_class = EAP_INPUT_CLASS;
1576 dip->prev = EAP_MIC_VOL;
1577 dip->next = AUDIO_MIXER_LAST;
1578 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
1579 dip->un.e.num_mem = 2;
1580 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
1581 sizeof dip->un.e.member[0].label.name);
1582 dip->un.e.member[0].ord = 0;
1583 strlcpy(dip->un.e.member[1].label.name, AudioNon,
1584 sizeof dip->un.e.member[1].label.name);
1585 dip->un.e.member[1].ord = 1;
1586 return (0);
1587 case EAP_OUTPUT_CLASS:
1588 dip->type = AUDIO_MIXER_CLASS;
1589 dip->mixer_class = EAP_OUTPUT_CLASS;
1590 dip->next = dip->prev = AUDIO_MIXER_LAST;
1591 strlcpy(dip->label.name, AudioCoutputs,
1592 sizeof dip->label.name);
1593 return (0);
1594 case EAP_RECORD_CLASS:
1595 dip->type = AUDIO_MIXER_CLASS;
1596 dip->mixer_class = EAP_RECORD_CLASS;
1597 dip->next = dip->prev = AUDIO_MIXER_LAST;
1598 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
1599 return (0);
1600 case EAP_INPUT_CLASS:
1601 dip->type = AUDIO_MIXER_CLASS;
1602 dip->mixer_class = EAP_INPUT_CLASS;
1603 dip->next = dip->prev = AUDIO_MIXER_LAST;
1604 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
1605 return (0);
1606 }
1607 return (ENXIO);
1608 }
1609
1610 void *
1611 eap_malloc(void *addr, int direction, size_t size, int pool, int flags)
1612 {
1613 struct eap_softc *sc = addr;
1614 struct eap_dma *p;
1615 int error;
1616
1617 p = malloc(sizeof(*p), pool, flags);
1618 if (!p)
1619 return (0);
1620 error = eap_allocmem(sc, size, 16, p);
1621 if (error) {
1622 free(p, pool);
1623 return (0);
1624 }
1625 p->next = sc->sc_dmas;
1626 sc->sc_dmas = p;
1627 return (KERNADDR(p));
1628 }
1629
1630 void
1631 eap_free(void *addr, void *ptr, int pool)
1632 {
1633 struct eap_softc *sc = addr;
1634 struct eap_dma **pp, *p;
1635
1636 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
1637 if (KERNADDR(p) == ptr) {
1638 eap_freemem(sc, p);
1639 *pp = p->next;
1640 free(p, pool);
1641 return;
1642 }
1643 }
1644 }
1645
1646 paddr_t
1647 eap_mappage(void *addr, void *mem, off_t off, int prot)
1648 {
1649 struct eap_softc *sc = addr;
1650 struct eap_dma *p;
1651
1652 if (off < 0)
1653 return (-1);
1654 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next)
1655 ;
1656 if (!p)
1657 return (-1);
1658 return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs,
1659 off, prot, BUS_DMA_WAITOK));
1660 }
1661
1662 int
1663 eap_get_props(void *addr)
1664 {
1665 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
1666 AUDIO_PROP_FULLDUPLEX);
1667 }
1668
1669 enum ac97_host_flags
1670 eap_flags_codec(void *v)
1671 {
1672 struct eap_softc *sc = v;
1673
1674 return (sc->flags);
1675 }
1676 #if NMIDI > 0
1677 int
1678 eap_midi_open(void *addr, int flags,
1679 void (*iintr)(void *, int),
1680 void (*ointr)(void *),
1681 void *arg)
1682 {
1683 struct eap_softc *sc = addr;
1684 u_int32_t uctrl;
1685
1686 sc->sc_iintr = iintr;
1687 sc->sc_ointr = ointr;
1688 sc->sc_arg = arg;
1689
1690 EWRITE4(sc, EAP_ICSC, EREAD4(sc, EAP_ICSC) | EAP_UART_EN);
1691 uctrl = 0;
1692 if (flags & FREAD)
1693 uctrl |= EAP_UC_RXINTEN;
1694 #if 0
1695
1696 if (flags & FWRITE)
1697 uctrl |= EAP_UC_TXINTEN; */
1698 #endif
1699 EWRITE1(sc, EAP_UART_CONTROL, uctrl);
1700
1701 return (0);
1702 }
1703
1704 void
1705 eap_midi_close(void *addr)
1706 {
1707 struct eap_softc *sc = addr;
1708
1709 tsleep(sc, PWAIT, "eapclm", hz/10);
1710 EWRITE1(sc, EAP_UART_CONTROL, 0);
1711 EWRITE4(sc, EAP_ICSC, EREAD4(sc, EAP_ICSC) & ~EAP_UART_EN);
1712
1713 sc->sc_iintr = 0;
1714 sc->sc_ointr = 0;
1715 }
1716
1717 int
1718 eap_midi_output(void *addr, int d)
1719 {
1720 struct eap_softc *sc = addr;
1721 int x;
1722
1723 for (x = 0; x != MIDI_BUSY_WAIT; x++) {
1724 if (EREAD1(sc, EAP_UART_STATUS) & EAP_US_TXRDY) {
1725 EWRITE1(sc, EAP_UART_DATA, d);
1726 return (0);
1727 }
1728 delay(MIDI_BUSY_DELAY);
1729 }
1730 return (EIO);
1731 }
1732
1733 void
1734 eap_midi_getinfo(void *addr, struct midi_info *mi)
1735 {
1736 mi->name = "AudioPCI MIDI UART";
1737 mi->props = MIDI_PROP_CAN_INPUT;
1738 }
1739
1740 #endif