FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/am7930.c
1 /* $NetBSD: am7930.c,v 1.44 2001/11/13 13:14:34 lukem Exp $ */
2
3 /*
4 * Copyright (c) 1995 Rolf Grossmann
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Rolf Grossmann.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Front-end attachment independent layer for AMD 79c30
35 * audio driver. No ISDN support.
36 */
37
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: am7930.c,v 1.44 2001/11/13 13:14:34 lukem Exp $");
40
41 #include "audio.h"
42 #if NAUDIO > 0
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/errno.h>
47 #include <sys/ioctl.h>
48 #include <sys/device.h>
49 #include <sys/proc.h>
50
51 #include <machine/bus.h>
52 #include <machine/autoconf.h>
53 #include <machine/cpu.h>
54
55 #include <sys/audioio.h>
56 #include <dev/audio_if.h>
57
58 #include <dev/ic/am7930reg.h>
59 #include <dev/ic/am7930var.h>
60
61 #ifdef AUDIO_DEBUG
62 int am7930debug = 0;
63 #define DPRINTF(x) if (am7930debug) printf x
64 #else
65 #define DPRINTF(x)
66 #endif
67
68
69 /* The following tables stolen from former (4.4Lite's) sys/sparc/bsd_audio.c */
70
71 /*
72 * gx, gr & stg gains. this table must contain 256 elements with
73 * the 0th being "infinity" (the magic value 9008). The remaining
74 * elements match sun's gain curve (but with higher resolution):
75 * -18 to 0dB in .16dB steps then 0 to 12dB in .08dB steps.
76 */
77 static const u_short gx_coeff[256] = {
78 0x9008, 0x8e7c, 0x8e51, 0x8e45, 0x8d42, 0x8d3b, 0x8c36, 0x8c33,
79 0x8b32, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b25, 0x8b23, 0x8b22, 0x8b22,
80 0x9122, 0x8b1a, 0x8aa3, 0x8aa3, 0x8b1c, 0x8aa6, 0x912d, 0x912b,
81 0x8aab, 0x8b12, 0x8aaa, 0x8ab2, 0x9132, 0x8ab4, 0x913c, 0x8abb,
82 0x9142, 0x9144, 0x9151, 0x8ad5, 0x8aeb, 0x8a79, 0x8a5a, 0x8a4a,
83 0x8b03, 0x91c2, 0x91bb, 0x8a3f, 0x8a33, 0x91b2, 0x9212, 0x9213,
84 0x8a2c, 0x921d, 0x8a23, 0x921a, 0x9222, 0x9223, 0x922d, 0x9231,
85 0x9234, 0x9242, 0x925b, 0x92dd, 0x92c1, 0x92b3, 0x92ab, 0x92a4,
86 0x92a2, 0x932b, 0x9341, 0x93d3, 0x93b2, 0x93a2, 0x943c, 0x94b2,
87 0x953a, 0x9653, 0x9782, 0x9e21, 0x9d23, 0x9cd2, 0x9c23, 0x9baa,
88 0x9bde, 0x9b33, 0x9b22, 0x9b1d, 0x9ab2, 0xa142, 0xa1e5, 0x9a3b,
89 0xa213, 0xa1a2, 0xa231, 0xa2eb, 0xa313, 0xa334, 0xa421, 0xa54b,
90 0xada4, 0xac23, 0xab3b, 0xaaab, 0xaa5c, 0xb1a3, 0xb2ca, 0xb3bd,
91 0xbe24, 0xbb2b, 0xba33, 0xc32b, 0xcb5a, 0xd2a2, 0xe31d, 0x0808,
92 0x72ba, 0x62c2, 0x5c32, 0x52db, 0x513e, 0x4cce, 0x43b2, 0x4243,
93 0x41b4, 0x3b12, 0x3bc3, 0x3df2, 0x34bd, 0x3334, 0x32c2, 0x3224,
94 0x31aa, 0x2a7b, 0x2aaa, 0x2b23, 0x2bba, 0x2c42, 0x2e23, 0x25bb,
95 0x242b, 0x240f, 0x231a, 0x22bb, 0x2241, 0x2223, 0x221f, 0x1a33,
96 0x1a4a, 0x1acd, 0x2132, 0x1b1b, 0x1b2c, 0x1b62, 0x1c12, 0x1c32,
97 0x1d1b, 0x1e71, 0x16b1, 0x1522, 0x1434, 0x1412, 0x1352, 0x1323,
98 0x1315, 0x12bc, 0x127a, 0x1235, 0x1226, 0x11a2, 0x1216, 0x0a2a,
99 0x11bc, 0x11d1, 0x1163, 0x0ac2, 0x0ab2, 0x0aab, 0x0b1b, 0x0b23,
100 0x0b33, 0x0c0f, 0x0bb3, 0x0c1b, 0x0c3e, 0x0cb1, 0x0d4c, 0x0ec1,
101 0x079a, 0x0614, 0x0521, 0x047c, 0x0422, 0x03b1, 0x03e3, 0x0333,
102 0x0322, 0x031c, 0x02aa, 0x02ba, 0x02f2, 0x0242, 0x0232, 0x0227,
103 0x0222, 0x021b, 0x01ad, 0x0212, 0x01b2, 0x01bb, 0x01cb, 0x01f6,
104 0x0152, 0x013a, 0x0133, 0x0131, 0x012c, 0x0123, 0x0122, 0x00a2,
105 0x011b, 0x011e, 0x0114, 0x00b1, 0x00aa, 0x00b3, 0x00bd, 0x00ba,
106 0x00c5, 0x00d3, 0x00f3, 0x0062, 0x0051, 0x0042, 0x003b, 0x0033,
107 0x0032, 0x002a, 0x002c, 0x0025, 0x0023, 0x0022, 0x001a, 0x0021,
108 0x001b, 0x001b, 0x001d, 0x0015, 0x0013, 0x0013, 0x0012, 0x0012,
109 0x000a, 0x000a, 0x0011, 0x0011, 0x000b, 0x000b, 0x000c, 0x000e,
110 };
111
112 /*
113 * second stage play gain.
114 */
115 static const u_short ger_coeff[] = {
116 0x431f, /* 5. dB */
117 0x331f, /* 5.5 dB */
118 0x40dd, /* 6. dB */
119 0x11dd, /* 6.5 dB */
120 0x440f, /* 7. dB */
121 0x411f, /* 7.5 dB */
122 0x311f, /* 8. dB */
123 0x5520, /* 8.5 dB */
124 0x10dd, /* 9. dB */
125 0x4211, /* 9.5 dB */
126 0x410f, /* 10. dB */
127 0x111f, /* 10.5 dB */
128 0x600b, /* 11. dB */
129 0x00dd, /* 11.5 dB */
130 0x4210, /* 12. dB */
131 0x110f, /* 13. dB */
132 0x7200, /* 14. dB */
133 0x2110, /* 15. dB */
134 0x2200, /* 15.9 dB */
135 0x000b, /* 16.9 dB */
136 0x000f /* 18. dB */
137 #define NGER (sizeof(ger_coeff) / sizeof(ger_coeff[0]))
138 };
139
140
141 /*
142 * Reset chip and set boot-time softc defaults.
143 */
144 void
145 am7930_init(sc, flag)
146 struct am7930_softc *sc;
147 int flag;
148 {
149
150 DPRINTF(("am7930_init()\n"));
151
152 /* set boot defaults */
153 sc->sc_rlevel = 128;
154 sc->sc_plevel = 128;
155 sc->sc_mlevel = 0;
156 sc->sc_out_port = AUDIOAMD_SPEAKER_VOL;
157 sc->sc_mic_mute = 0;
158
159 /* disable sample interrupts */
160 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4, 0);
161
162 /* initialise voice and data, and disable interrupts */
163 AM7930_IWRITE(sc, AM7930_IREG_INIT,
164 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
165
166 if (flag == AUDIOAMD_DMA_MODE) {
167
168 /* configure PP for serial (SBP) mode */
169 AM7930_IWRITE(sc, AM7930_IREG_PP_PPCR1, AM7930_PPCR1_SBP);
170
171 /*
172 * Initialise the MUX unit - route the MAP to the PP
173 */
174 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1,
175 (AM7930_MCRCHAN_BA << 4) | AM7930_MCRCHAN_BD);
176 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, AM7930_MCRCHAN_NC);
177 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3, AM7930_MCRCHAN_NC);
178
179 } else {
180
181 /*
182 * Initialize the MUX unit. We use MCR3 to route the MAP
183 * through channel Bb. MCR1 and MCR2 are unused.
184 * Setting the INT enable bit in MCR4 will generate an
185 * interrupt on each converted audio sample.
186 */
187 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1, 0);
188 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, 0);
189 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3,
190 (AM7930_MCRCHAN_BB << 4) | AM7930_MCRCHAN_BA);
191 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4,
192 AM7930_MCR4_INT_ENABLE);
193 }
194
195 }
196
197
198 int
199 am7930_open(addr, flags)
200 void *addr;
201 int flags;
202 {
203 struct am7930_softc *sc = addr;
204
205 DPRINTF(("sa_open: unit %p\n", sc));
206
207 if (sc->sc_open)
208 return (EBUSY);
209 sc->sc_open = 1;
210 sc->sc_locked = 0;
211
212 sc->sc_glue->onopen(sc);
213
214 DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
215
216 return (0);
217 }
218
219 void
220 am7930_close(addr)
221 void *addr;
222 {
223 struct am7930_softc *sc = addr;
224
225 DPRINTF(("sa_close: sc=%p\n", sc));
226
227 sc->sc_glue->onclose(sc);
228 sc->sc_open = 0;
229
230 DPRINTF(("sa_close: closed.\n"));
231 }
232
233
234 /*
235 * XXX should be extended to handle a few of the more common formats.
236 */
237 int
238 am7930_set_params(addr, setmode, usemode, p, r)
239 void *addr;
240 int setmode, usemode;
241 struct audio_params *p, *r;
242 {
243 struct am7930_softc *sc = addr;
244
245 if ((usemode & AUMODE_PLAY) == AUMODE_PLAY) {
246 if (p->sample_rate < 7500 || p->sample_rate > 8500 ||
247 p->encoding != AUDIO_ENCODING_ULAW ||
248 p->precision != 8 ||
249 p->channels != 1)
250 return EINVAL;
251 p->sample_rate = 8000;
252 if (sc->sc_glue->factor > 1) {
253 p->factor = sc->sc_glue->factor;
254 p->sw_code = sc->sc_glue->output_conv;
255 }
256 }
257 if ((usemode & AUMODE_RECORD) == AUMODE_RECORD) {
258 if (r->sample_rate < 7500 || r->sample_rate > 8500 ||
259 r->encoding != AUDIO_ENCODING_ULAW ||
260 r->precision != 8 ||
261 r->channels != 1)
262 return EINVAL;
263 r->sample_rate = 8000;
264 if (sc->sc_glue->factor > 1) {
265 r->factor = sc->sc_glue->factor;
266 r->sw_code = sc->sc_glue->input_conv;
267 }
268 }
269
270 return 0;
271 }
272
273 int
274 am7930_query_encoding(addr, fp)
275 void *addr;
276 struct audio_encoding *fp;
277 {
278 switch (fp->index) { /* ??? */
279 case 0:
280 strcpy(fp->name, AudioEmulaw);
281 fp->encoding = AUDIO_ENCODING_ULAW;
282 fp->precision = 8;
283 fp->flags = 0;
284 break;
285 default:
286 return(EINVAL);
287 /*NOTREACHED*/
288 }
289 return(0);
290 }
291
292
293 int
294 am7930_round_blocksize(addr, blk)
295 void *addr;
296 int blk;
297 {
298 return(blk);
299 }
300
301
302 int
303 am7930_commit_settings(addr)
304 void *addr;
305 {
306 struct am7930_softc *sc = addr;
307 u_int16_t ger, gr, gx, stgr;
308 u_int8_t mmr2, mmr3;
309 int s, level;
310
311 DPRINTF(("sa_commit.\n"));
312
313 gx = gx_coeff[sc->sc_rlevel];
314 stgr = gx_coeff[sc->sc_mlevel];
315
316 level = (sc->sc_plevel * (256 + NGER)) >> 8;
317 if (level >= 256) {
318 ger = ger_coeff[level - 256];
319 gr = gx_coeff[255];
320 } else {
321 ger = ger_coeff[0];
322 gr = gx_coeff[level];
323 }
324
325 s = splaudio();
326
327 mmr2 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR2);
328 if (sc->sc_out_port == AUDIOAMD_SPEAKER_VOL)
329 mmr2 |= AM7930_MMR2_LS;
330 else
331 mmr2 &= ~AM7930_MMR2_LS;
332 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR2, mmr2);
333
334 mmr3 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR3);
335 if (sc->sc_mic_mute)
336 mmr3 |= AM7930_MMR3_MUTE;
337 else
338 mmr3 &= ~AM7930_MMR3_MUTE;
339 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR3, mmr3);
340
341 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR1,
342 AM7930_MMR1_GX | AM7930_MMR1_GER |
343 AM7930_MMR1_GR | AM7930_MMR1_STG);
344
345 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GX, gx);
346 AM7930_IWRITE16(sc, AM7930_IREG_MAP_STG, stgr);
347 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GR, gr);
348 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GER, ger);
349
350 splx(s);
351
352 return(0);
353 }
354
355
356 int
357 am7930_halt_output(addr)
358 void *addr;
359 {
360 struct am7930_softc *sc = addr;
361
362 /* XXX only halt, if input is also halted ?? */
363 AM7930_IWRITE(sc, AM7930_IREG_INIT,
364 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
365 sc->sc_locked = 0;
366
367 return(0);
368 }
369
370
371 int
372 am7930_halt_input(addr)
373 void *addr;
374 {
375 struct am7930_softc *sc = addr;
376
377 /* XXX only halt, if output is also halted ?? */
378 AM7930_IWRITE(sc, AM7930_IREG_INIT,
379 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
380 sc->sc_locked = 0;
381
382 return(0);
383 }
384
385
386 /*
387 * XXX chip is full-duplex, but really attach-dependent.
388 * For now we know of no half-duplex attachments.
389 */
390 int
391 am7930_get_props(addr)
392 void *addr;
393 {
394 return AUDIO_PROP_FULLDUPLEX;
395 }
396
397 /*
398 * Attach-dependent channel set/query
399 */
400 int
401 am7930_set_port(addr, cp)
402 void *addr;
403 mixer_ctrl_t *cp;
404 {
405 struct am7930_softc *sc = addr;
406
407 DPRINTF(("am7930_set_port: port=%d", cp->dev));
408
409 if (cp->dev == AUDIOAMD_RECORD_SOURCE ||
410 cp->dev == AUDIOAMD_MONITOR_OUTPUT ||
411 cp->dev == AUDIOAMD_MIC_MUTE) {
412 if (cp->type != AUDIO_MIXER_ENUM)
413 return(EINVAL);
414 } else if (cp->type != AUDIO_MIXER_VALUE ||
415 cp->un.value.num_channels != 1) {
416 return(EINVAL);
417 }
418
419 switch(cp->dev) {
420 case AUDIOAMD_MIC_VOL:
421 sc->sc_rlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
422 break;
423 case AUDIOAMD_SPEAKER_VOL:
424 case AUDIOAMD_HEADPHONES_VOL:
425 sc->sc_plevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
426 break;
427 case AUDIOAMD_MONITOR_VOL:
428 sc->sc_mlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
429 break;
430 case AUDIOAMD_RECORD_SOURCE:
431 if (cp->un.ord != AUDIOAMD_MIC_VOL)
432 return EINVAL;
433 break;
434 case AUDIOAMD_MIC_MUTE:
435 sc->sc_mic_mute = cp->un.ord;
436 break;
437 case AUDIOAMD_MONITOR_OUTPUT:
438 if (cp->un.ord != AUDIOAMD_SPEAKER_VOL &&
439 cp->un.ord != AUDIOAMD_HEADPHONES_VOL)
440 return EINVAL;
441 sc->sc_out_port = cp->un.ord;
442 break;
443 default:
444 return(EINVAL);
445 /* NOTREACHED */
446 }
447 return 0;
448 }
449
450 int
451 am7930_get_port(addr, cp)
452 void *addr;
453 mixer_ctrl_t *cp;
454 {
455 struct am7930_softc *sc = addr;
456
457 DPRINTF(("am7930_get_port: port=%d\n", cp->dev));
458
459 if (cp->dev == AUDIOAMD_RECORD_SOURCE ||
460 cp->dev == AUDIOAMD_MONITOR_OUTPUT ||
461 cp->dev == AUDIOAMD_MIC_MUTE) {
462 if (cp->type != AUDIO_MIXER_ENUM)
463 return(EINVAL);
464 } else if (cp->type != AUDIO_MIXER_VALUE ||
465 cp->un.value.num_channels != 1) {
466 return(EINVAL);
467 }
468
469 switch(cp->dev) {
470 case AUDIOAMD_MIC_VOL:
471 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_rlevel;
472 break;
473 case AUDIOAMD_SPEAKER_VOL:
474 case AUDIOAMD_HEADPHONES_VOL:
475 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_plevel;
476 break;
477 case AUDIOAMD_MONITOR_VOL:
478 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_mlevel;
479 break;
480 case AUDIOAMD_RECORD_SOURCE:
481 cp->un.ord = AUDIOAMD_MIC_VOL;
482 break;
483 case AUDIOAMD_MIC_MUTE:
484 cp->un.ord = sc->sc_mic_mute;
485 break;
486 case AUDIOAMD_MONITOR_OUTPUT:
487 cp->un.ord = sc->sc_out_port;
488 break;
489 default:
490 return(EINVAL);
491 /* NOTREACHED */
492 }
493 return 0;
494 }
495
496
497 /*
498 * Define mixer control facilities.
499 */
500 int
501 am7930_query_devinfo(addr, dip)
502 void *addr;
503 mixer_devinfo_t *dip;
504 {
505
506 DPRINTF(("am7930_query_devinfo()\n"));
507
508 switch(dip->index) {
509 case AUDIOAMD_MIC_VOL:
510 dip->type = AUDIO_MIXER_VALUE;
511 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
512 dip->prev = AUDIO_MIXER_LAST;
513 dip->next = AUDIOAMD_MIC_MUTE;
514 strcpy(dip->label.name, AudioNmicrophone);
515 dip->un.v.num_channels = 1;
516 strcpy(dip->un.v.units.name, AudioNvolume);
517 break;
518 case AUDIOAMD_SPEAKER_VOL:
519 dip->type = AUDIO_MIXER_VALUE;
520 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
521 dip->prev = dip->next = AUDIO_MIXER_LAST;
522 strcpy(dip->label.name, AudioNspeaker);
523 dip->un.v.num_channels = 1;
524 strcpy(dip->un.v.units.name, AudioNvolume);
525 break;
526 case AUDIOAMD_HEADPHONES_VOL:
527 dip->type = AUDIO_MIXER_VALUE;
528 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
529 dip->prev = dip->next = AUDIO_MIXER_LAST;
530 strcpy(dip->label.name, AudioNheadphone);
531 dip->un.v.num_channels = 1;
532 strcpy(dip->un.v.units.name, AudioNvolume);
533 break;
534 case AUDIOAMD_MONITOR_VOL:
535 dip->type = AUDIO_MIXER_VALUE;
536 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
537 dip->prev = dip->next = AUDIO_MIXER_LAST;
538 strcpy(dip->label.name, AudioNmonitor);
539 dip->un.v.num_channels = 1;
540 strcpy(dip->un.v.units.name, AudioNvolume);
541 break;
542 case AUDIOAMD_RECORD_SOURCE:
543 dip->type = AUDIO_MIXER_ENUM;
544 dip->mixer_class = AUDIOAMD_RECORD_CLASS;
545 dip->next = dip->prev = AUDIO_MIXER_LAST;
546 strcpy(dip->label.name, AudioNsource);
547 dip->un.e.num_mem = 1;
548 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
549 dip->un.e.member[0].ord = AUDIOAMD_MIC_VOL;
550 break;
551 case AUDIOAMD_MONITOR_OUTPUT:
552 dip->type = AUDIO_MIXER_ENUM;
553 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
554 dip->next = dip->prev = AUDIO_MIXER_LAST;
555 strcpy(dip->label.name, AudioNoutput);
556 dip->un.e.num_mem = 2;
557 strcpy(dip->un.e.member[0].label.name, AudioNspeaker);
558 dip->un.e.member[0].ord = AUDIOAMD_SPEAKER_VOL;
559 strcpy(dip->un.e.member[1].label.name, AudioNheadphone);
560 dip->un.e.member[1].ord = AUDIOAMD_HEADPHONES_VOL;
561 break;
562 case AUDIOAMD_MIC_MUTE:
563 dip->type = AUDIO_MIXER_ENUM;
564 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
565 dip->prev = AUDIOAMD_MIC_VOL;
566 dip->next = AUDIO_MIXER_LAST;
567 strcpy(dip->label.name, AudioNmute);
568 dip->un.e.num_mem = 2;
569 strcpy(dip->un.e.member[0].label.name, AudioNoff);
570 dip->un.e.member[0].ord = 0;
571 strcpy(dip->un.e.member[1].label.name, AudioNon);
572 dip->un.e.member[1].ord = 1;
573 break;
574 case AUDIOAMD_INPUT_CLASS:
575 dip->type = AUDIO_MIXER_CLASS;
576 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
577 dip->next = dip->prev = AUDIO_MIXER_LAST;
578 strcpy(dip->label.name, AudioCinputs);
579 break;
580 case AUDIOAMD_OUTPUT_CLASS:
581 dip->type = AUDIO_MIXER_CLASS;
582 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
583 dip->next = dip->prev = AUDIO_MIXER_LAST;
584 strcpy(dip->label.name, AudioCoutputs);
585 break;
586 case AUDIOAMD_RECORD_CLASS:
587 dip->type = AUDIO_MIXER_CLASS;
588 dip->mixer_class = AUDIOAMD_RECORD_CLASS;
589 dip->next = dip->prev = AUDIO_MIXER_LAST;
590 strcpy(dip->label.name, AudioCrecord);
591 break;
592 case AUDIOAMD_MONITOR_CLASS:
593 dip->type = AUDIO_MIXER_CLASS;
594 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
595 dip->next = dip->prev = AUDIO_MIXER_LAST;
596 strcpy(dip->label.name, AudioCmonitor);
597 break;
598 default:
599 return ENXIO;
600 /*NOTREACHED*/
601 }
602
603 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
604
605 return(0);
606 }
607
608 #endif /* NAUDIO */
Cache object: 341b470798647af9100f6ef516845e9c
|