FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/am7930.c
1 /* $NetBSD: am7930.c,v 1.47 2005/01/15 15:19:52 kent 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.47 2005/01/15 15:19:52 kent 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 uint16_t 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 uint16_t 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(struct am7930_softc *sc, int flag)
146 {
147
148 DPRINTF(("am7930_init()\n"));
149
150 /* set boot defaults */
151 sc->sc_rlevel = 128;
152 sc->sc_plevel = 128;
153 sc->sc_mlevel = 0;
154 sc->sc_out_port = AUDIOAMD_SPEAKER_VOL;
155 sc->sc_mic_mute = 0;
156
157 /* disable sample interrupts */
158 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4, 0);
159
160 /* initialise voice and data, and disable interrupts */
161 AM7930_IWRITE(sc, AM7930_IREG_INIT,
162 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
163
164 if (flag == AUDIOAMD_DMA_MODE) {
165
166 /* configure PP for serial (SBP) mode */
167 AM7930_IWRITE(sc, AM7930_IREG_PP_PPCR1, AM7930_PPCR1_SBP);
168
169 /*
170 * Initialise the MUX unit - route the MAP to the PP
171 */
172 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1,
173 (AM7930_MCRCHAN_BA << 4) | AM7930_MCRCHAN_BD);
174 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, AM7930_MCRCHAN_NC);
175 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3, AM7930_MCRCHAN_NC);
176
177 } else {
178
179 /*
180 * Initialize the MUX unit. We use MCR3 to route the MAP
181 * through channel Bb. MCR1 and MCR2 are unused.
182 * Setting the INT enable bit in MCR4 will generate an
183 * interrupt on each converted audio sample.
184 */
185 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1, 0);
186 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, 0);
187 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3,
188 (AM7930_MCRCHAN_BB << 4) | AM7930_MCRCHAN_BA);
189 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4,
190 AM7930_MCR4_INT_ENABLE);
191 }
192
193 }
194
195 int
196 am7930_open(void *addr, int flags)
197 {
198 struct am7930_softc *sc;
199
200 sc = addr;
201 DPRINTF(("sa_open: unit %p\n", sc));
202 sc->sc_glue->onopen(sc);
203 DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
204 return 0;
205 }
206
207 void
208 am7930_close(void *addr)
209 {
210 struct am7930_softc *sc;
211
212 sc = addr;
213 DPRINTF(("sa_close: sc=%p\n", sc));
214 sc->sc_glue->onclose(sc);
215 DPRINTF(("sa_close: closed.\n"));
216 }
217
218 /*
219 * XXX should be extended to handle a few of the more common formats.
220 */
221 int
222 am7930_set_params(void *addr, int setmode, int usemode, audio_params_t *p,
223 audio_params_t *r, stream_filter_list_t *pfil, stream_filter_list_t *rfil)
224 {
225 audio_params_t hw;
226 struct am7930_softc *sc;
227
228 sc = addr;
229 if ((usemode & AUMODE_PLAY) == AUMODE_PLAY) {
230 if (p->sample_rate < 7500 || p->sample_rate > 8500 ||
231 p->encoding != AUDIO_ENCODING_ULAW ||
232 p->precision != 8 ||
233 p->channels != 1)
234 return EINVAL;
235 p->sample_rate = 8000;
236 if (sc->sc_glue->output_conv != NULL) {
237 hw = *p;
238 hw.encoding = AUDIO_ENCODING_NONE;
239 hw.precision *= sc->sc_glue->factor;
240 pfil->append(pfil, sc->sc_glue->output_conv, &hw);
241 }
242 }
243 if ((usemode & AUMODE_RECORD) == AUMODE_RECORD) {
244 if (r->sample_rate < 7500 || r->sample_rate > 8500 ||
245 r->encoding != AUDIO_ENCODING_ULAW ||
246 r->precision != 8 ||
247 r->channels != 1)
248 return EINVAL;
249 r->sample_rate = 8000;
250 if (sc->sc_glue->input_conv != NULL) {
251 hw = *r;
252 hw.encoding = AUDIO_ENCODING_NONE;
253 hw.precision *= sc->sc_glue->factor;
254 pfil->append(rfil, sc->sc_glue->input_conv, &hw);
255 }
256 }
257
258 return 0;
259 }
260
261 int
262 am7930_query_encoding(void *addr, struct audio_encoding *fp)
263 {
264 switch (fp->index) {
265 case 0:
266 strcpy(fp->name, AudioEmulaw);
267 fp->encoding = AUDIO_ENCODING_ULAW;
268 fp->precision = 8;
269 fp->flags = 0;
270 break;
271 default:
272 return EINVAL;
273 /*NOTREACHED*/
274 }
275 return 0;
276 }
277
278 int
279 am7930_round_blocksize(void *addr, int blk,
280 int mode, const audio_params_t *param)
281 {
282 return blk;
283 }
284
285 int
286 am7930_commit_settings(void *addr)
287 {
288 struct am7930_softc *sc;
289 uint16_t ger, gr, gx, stgr;
290 uint8_t mmr2, mmr3;
291 int s, level;
292
293 DPRINTF(("sa_commit.\n"));
294 sc = addr;
295 gx = gx_coeff[sc->sc_rlevel];
296 stgr = gx_coeff[sc->sc_mlevel];
297
298 level = (sc->sc_plevel * (256 + NGER)) >> 8;
299 if (level >= 256) {
300 ger = ger_coeff[level - 256];
301 gr = gx_coeff[255];
302 } else {
303 ger = ger_coeff[0];
304 gr = gx_coeff[level];
305 }
306
307 s = splaudio();
308
309 mmr2 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR2);
310 if (sc->sc_out_port == AUDIOAMD_SPEAKER_VOL)
311 mmr2 |= AM7930_MMR2_LS;
312 else
313 mmr2 &= ~AM7930_MMR2_LS;
314 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR2, mmr2);
315
316 mmr3 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR3);
317 if (sc->sc_mic_mute)
318 mmr3 |= AM7930_MMR3_MUTE;
319 else
320 mmr3 &= ~AM7930_MMR3_MUTE;
321 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR3, mmr3);
322
323 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR1,
324 AM7930_MMR1_GX | AM7930_MMR1_GER |
325 AM7930_MMR1_GR | AM7930_MMR1_STG);
326
327 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GX, gx);
328 AM7930_IWRITE16(sc, AM7930_IREG_MAP_STG, stgr);
329 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GR, gr);
330 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GER, ger);
331
332 splx(s);
333
334 return 0;
335 }
336
337 int
338 am7930_halt_output(void *addr)
339 {
340 struct am7930_softc *sc;
341
342 sc = addr;
343 /* XXX only halt, if input is also halted ?? */
344 AM7930_IWRITE(sc, AM7930_IREG_INIT,
345 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
346 return 0;
347 }
348
349 int
350 am7930_halt_input(void *addr)
351 {
352 struct am7930_softc *sc;
353
354 sc = addr;
355 /* XXX only halt, if output is also halted ?? */
356 AM7930_IWRITE(sc, AM7930_IREG_INIT,
357 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
358 return 0;
359 }
360
361 /*
362 * XXX chip is full-duplex, but really attach-dependent.
363 * For now we know of no half-duplex attachments.
364 */
365 int
366 am7930_get_props(void *addr)
367 {
368 return AUDIO_PROP_FULLDUPLEX;
369 }
370
371 /*
372 * Attach-dependent channel set/query
373 */
374 int
375 am7930_set_port(void *addr, mixer_ctrl_t *cp)
376 {
377 struct am7930_softc *sc;
378
379 DPRINTF(("am7930_set_port: port=%d", cp->dev));
380 sc = addr;
381 if (cp->dev == AUDIOAMD_RECORD_SOURCE ||
382 cp->dev == AUDIOAMD_MONITOR_OUTPUT ||
383 cp->dev == AUDIOAMD_MIC_MUTE) {
384 if (cp->type != AUDIO_MIXER_ENUM)
385 return EINVAL;
386 } else if (cp->type != AUDIO_MIXER_VALUE ||
387 cp->un.value.num_channels != 1) {
388 return EINVAL;
389 }
390
391 switch(cp->dev) {
392 case AUDIOAMD_MIC_VOL:
393 sc->sc_rlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
394 break;
395 case AUDIOAMD_SPEAKER_VOL:
396 case AUDIOAMD_HEADPHONES_VOL:
397 sc->sc_plevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
398 break;
399 case AUDIOAMD_MONITOR_VOL:
400 sc->sc_mlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
401 break;
402 case AUDIOAMD_RECORD_SOURCE:
403 if (cp->un.ord != AUDIOAMD_MIC_VOL)
404 return EINVAL;
405 break;
406 case AUDIOAMD_MIC_MUTE:
407 sc->sc_mic_mute = cp->un.ord;
408 break;
409 case AUDIOAMD_MONITOR_OUTPUT:
410 if (cp->un.ord != AUDIOAMD_SPEAKER_VOL &&
411 cp->un.ord != AUDIOAMD_HEADPHONES_VOL)
412 return EINVAL;
413 sc->sc_out_port = cp->un.ord;
414 break;
415 default:
416 return EINVAL;
417 /* NOTREACHED */
418 }
419 return 0;
420 }
421
422 int
423 am7930_get_port(void *addr, mixer_ctrl_t *cp)
424 {
425 struct am7930_softc *sc;
426
427 DPRINTF(("am7930_get_port: port=%d\n", cp->dev));
428 sc = addr;
429 if (cp->dev == AUDIOAMD_RECORD_SOURCE ||
430 cp->dev == AUDIOAMD_MONITOR_OUTPUT ||
431 cp->dev == AUDIOAMD_MIC_MUTE) {
432 if (cp->type != AUDIO_MIXER_ENUM)
433 return EINVAL;
434 } else if (cp->type != AUDIO_MIXER_VALUE ||
435 cp->un.value.num_channels != 1) {
436 return EINVAL;
437 }
438
439 switch(cp->dev) {
440 case AUDIOAMD_MIC_VOL:
441 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_rlevel;
442 break;
443 case AUDIOAMD_SPEAKER_VOL:
444 case AUDIOAMD_HEADPHONES_VOL:
445 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_plevel;
446 break;
447 case AUDIOAMD_MONITOR_VOL:
448 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_mlevel;
449 break;
450 case AUDIOAMD_RECORD_SOURCE:
451 cp->un.ord = AUDIOAMD_MIC_VOL;
452 break;
453 case AUDIOAMD_MIC_MUTE:
454 cp->un.ord = sc->sc_mic_mute;
455 break;
456 case AUDIOAMD_MONITOR_OUTPUT:
457 cp->un.ord = sc->sc_out_port;
458 break;
459 default:
460 return EINVAL;
461 /* NOTREACHED */
462 }
463 return 0;
464 }
465
466
467 /*
468 * Define mixer control facilities.
469 */
470 int
471 am7930_query_devinfo(void *addr, mixer_devinfo_t *dip)
472 {
473
474 DPRINTF(("am7930_query_devinfo()\n"));
475
476 switch(dip->index) {
477 case AUDIOAMD_MIC_VOL:
478 dip->type = AUDIO_MIXER_VALUE;
479 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
480 dip->prev = AUDIO_MIXER_LAST;
481 dip->next = AUDIOAMD_MIC_MUTE;
482 strcpy(dip->label.name, AudioNmicrophone);
483 dip->un.v.num_channels = 1;
484 strcpy(dip->un.v.units.name, AudioNvolume);
485 break;
486 case AUDIOAMD_SPEAKER_VOL:
487 dip->type = AUDIO_MIXER_VALUE;
488 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
489 dip->prev = dip->next = AUDIO_MIXER_LAST;
490 strcpy(dip->label.name, AudioNspeaker);
491 dip->un.v.num_channels = 1;
492 strcpy(dip->un.v.units.name, AudioNvolume);
493 break;
494 case AUDIOAMD_HEADPHONES_VOL:
495 dip->type = AUDIO_MIXER_VALUE;
496 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
497 dip->prev = dip->next = AUDIO_MIXER_LAST;
498 strcpy(dip->label.name, AudioNheadphone);
499 dip->un.v.num_channels = 1;
500 strcpy(dip->un.v.units.name, AudioNvolume);
501 break;
502 case AUDIOAMD_MONITOR_VOL:
503 dip->type = AUDIO_MIXER_VALUE;
504 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
505 dip->prev = dip->next = AUDIO_MIXER_LAST;
506 strcpy(dip->label.name, AudioNmonitor);
507 dip->un.v.num_channels = 1;
508 strcpy(dip->un.v.units.name, AudioNvolume);
509 break;
510 case AUDIOAMD_RECORD_SOURCE:
511 dip->type = AUDIO_MIXER_ENUM;
512 dip->mixer_class = AUDIOAMD_RECORD_CLASS;
513 dip->next = dip->prev = AUDIO_MIXER_LAST;
514 strcpy(dip->label.name, AudioNsource);
515 dip->un.e.num_mem = 1;
516 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
517 dip->un.e.member[0].ord = AUDIOAMD_MIC_VOL;
518 break;
519 case AUDIOAMD_MONITOR_OUTPUT:
520 dip->type = AUDIO_MIXER_ENUM;
521 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
522 dip->next = dip->prev = AUDIO_MIXER_LAST;
523 strcpy(dip->label.name, AudioNoutput);
524 dip->un.e.num_mem = 2;
525 strcpy(dip->un.e.member[0].label.name, AudioNspeaker);
526 dip->un.e.member[0].ord = AUDIOAMD_SPEAKER_VOL;
527 strcpy(dip->un.e.member[1].label.name, AudioNheadphone);
528 dip->un.e.member[1].ord = AUDIOAMD_HEADPHONES_VOL;
529 break;
530 case AUDIOAMD_MIC_MUTE:
531 dip->type = AUDIO_MIXER_ENUM;
532 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
533 dip->prev = AUDIOAMD_MIC_VOL;
534 dip->next = AUDIO_MIXER_LAST;
535 strcpy(dip->label.name, AudioNmute);
536 dip->un.e.num_mem = 2;
537 strcpy(dip->un.e.member[0].label.name, AudioNoff);
538 dip->un.e.member[0].ord = 0;
539 strcpy(dip->un.e.member[1].label.name, AudioNon);
540 dip->un.e.member[1].ord = 1;
541 break;
542 case AUDIOAMD_INPUT_CLASS:
543 dip->type = AUDIO_MIXER_CLASS;
544 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
545 dip->next = dip->prev = AUDIO_MIXER_LAST;
546 strcpy(dip->label.name, AudioCinputs);
547 break;
548 case AUDIOAMD_OUTPUT_CLASS:
549 dip->type = AUDIO_MIXER_CLASS;
550 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
551 dip->next = dip->prev = AUDIO_MIXER_LAST;
552 strcpy(dip->label.name, AudioCoutputs);
553 break;
554 case AUDIOAMD_RECORD_CLASS:
555 dip->type = AUDIO_MIXER_CLASS;
556 dip->mixer_class = AUDIOAMD_RECORD_CLASS;
557 dip->next = dip->prev = AUDIO_MIXER_LAST;
558 strcpy(dip->label.name, AudioCrecord);
559 break;
560 case AUDIOAMD_MONITOR_CLASS:
561 dip->type = AUDIO_MIXER_CLASS;
562 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
563 dip->next = dip->prev = AUDIO_MIXER_LAST;
564 strcpy(dip->label.name, AudioCmonitor);
565 break;
566 default:
567 return ENXIO;
568 /*NOTREACHED*/
569 }
570
571 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
572
573 return 0;
574 }
575
576 #endif /* NAUDIO */
Cache object: 1d2d6968897d103aec188d9ada4010e5
|