ym.c revision 1.4 1 1.4 augustss /* $NetBSD: ym.c,v 1.4 1998/08/17 21:16:15 augustss Exp $ */
2 1.1 augustss
3 1.1 augustss
4 1.1 augustss /*
5 1.1 augustss * Copyright (c) 1998 Constantine Sapuntzakis. All rights reserved.
6 1.1 augustss *
7 1.1 augustss * Redistribution and use in source and binary forms, with or without
8 1.1 augustss * modification, are permitted provided that the following conditions
9 1.1 augustss * are met:
10 1.1 augustss * 1. Redistributions of source code must retain the above copyright
11 1.1 augustss * notice, this list of conditions and the following disclaimer.
12 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 augustss * notice, this list of conditions and the following disclaimer in the
14 1.1 augustss * documentation and/or other materials provided with the distribution.
15 1.1 augustss * 3. The name of the author may not be used to endorse or promote products
16 1.1 augustss * derived from this software without specific prior written permission.
17 1.1 augustss *
18 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.1 augustss * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.1 augustss * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.1 augustss * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 augustss * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 1.1 augustss * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.1 augustss * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.1 augustss * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.1 augustss * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 1.1 augustss * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.1 augustss */
29 1.1 augustss
30 1.1 augustss /*
31 1.1 augustss * Original code from OpenBSD.
32 1.1 augustss */
33 1.1 augustss
34 1.1 augustss
35 1.1 augustss #include <sys/param.h>
36 1.1 augustss #include <sys/systm.h>
37 1.1 augustss #include <sys/errno.h>
38 1.1 augustss #include <sys/ioctl.h>
39 1.1 augustss #include <sys/syslog.h>
40 1.1 augustss #include <sys/device.h>
41 1.1 augustss #include <sys/proc.h>
42 1.1 augustss #include <sys/buf.h>
43 1.1 augustss
44 1.1 augustss #include <machine/cpu.h>
45 1.1 augustss #include <machine/intr.h>
46 1.1 augustss #include <machine/bus.h>
47 1.1 augustss
48 1.1 augustss #include <sys/audioio.h>
49 1.1 augustss #include <dev/audio_if.h>
50 1.1 augustss
51 1.1 augustss #include <dev/isa/isavar.h>
52 1.1 augustss #include <dev/isa/isadmavar.h>
53 1.1 augustss
54 1.1 augustss #include <dev/ic/ad1848reg.h>
55 1.1 augustss #include <dev/isa/ad1848var.h>
56 1.1 augustss #include <dev/ic/opl3sa3.h>
57 1.1 augustss #include <dev/isa/ymvar.h>
58 1.1 augustss
59 1.1 augustss
60 1.1 augustss int ym_getdev __P((void *, struct audio_device *));
61 1.1 augustss int ym_mixer_set_port __P((void *, mixer_ctrl_t *));
62 1.1 augustss int ym_mixer_get_port __P((void *, mixer_ctrl_t *));
63 1.1 augustss int ym_query_devinfo __P((void *, mixer_devinfo_t *));
64 1.1 augustss
65 1.1 augustss static void ym_mute __P((struct ym_softc *, int, int));
66 1.2 augustss static void ym_set_master_gain __P((struct ym_softc *, struct ad1848_volume*));
67 1.1 augustss static void ym_set_mic_gain __P((struct ym_softc *, struct ad1848_volume *));
68 1.1 augustss
69 1.1 augustss
70 1.1 augustss
71 1.1 augustss struct audio_hw_if ym_hw_if = {
72 1.1 augustss ad1848_open,
73 1.1 augustss ad1848_close,
74 1.1 augustss NULL,
75 1.1 augustss ad1848_query_encoding,
76 1.1 augustss ad1848_set_params,
77 1.1 augustss ad1848_round_blocksize,
78 1.1 augustss ad1848_commit_settings,
79 1.1 augustss ad1848_dma_init_output,
80 1.1 augustss ad1848_dma_init_input,
81 1.1 augustss ad1848_dma_output,
82 1.1 augustss ad1848_dma_input,
83 1.1 augustss ad1848_halt_out_dma,
84 1.1 augustss ad1848_halt_in_dma,
85 1.1 augustss NULL,
86 1.1 augustss ym_getdev,
87 1.1 augustss NULL,
88 1.1 augustss ym_mixer_set_port,
89 1.1 augustss ym_mixer_get_port,
90 1.1 augustss ym_query_devinfo,
91 1.1 augustss ad1848_malloc,
92 1.1 augustss ad1848_free,
93 1.1 augustss ad1848_round,
94 1.1 augustss ad1848_mappage,
95 1.1 augustss ad1848_get_props,
96 1.1 augustss };
97 1.1 augustss
98 1.1 augustss
99 1.1 augustss struct audio_device ym_device = {
100 1.1 augustss "ym,ad1848",
101 1.1 augustss "",
102 1.1 augustss "ym"
103 1.1 augustss };
104 1.1 augustss
105 1.1 augustss static __inline int ym_read __P((struct ym_softc *, int));
106 1.1 augustss static __inline void ym_write __P((struct ym_softc *, int, int));
107 1.1 augustss
108 1.1 augustss void
109 1.1 augustss ym_attach(sc)
110 1.2 augustss struct ym_softc *sc;
111 1.1 augustss {
112 1.2 augustss struct ad1848_volume vol_mid = {220, 220};
113 1.2 augustss struct ad1848_volume vol_0 = {0, 0};
114 1.1 augustss
115 1.2 augustss sc->sc_ih = isa_intr_establish(sc->sc_ic, sc->ym_irq, IST_EDGE,
116 1.2 augustss IPL_AUDIO, ad1848_intr, &sc->sc_ad1848);
117 1.1 augustss
118 1.2 augustss ad1848_attach(&sc->sc_ad1848);
119 1.2 augustss printf("\n");
120 1.2 augustss sc->sc_ad1848.parent = sc;
121 1.2 augustss
122 1.2 augustss /* Establish chip in well known mode */
123 1.2 augustss ym_set_master_gain(sc, &vol_mid);
124 1.2 augustss ym_set_mic_gain(sc, &vol_0);
125 1.2 augustss sc->master_mute = 0;
126 1.2 augustss ym_mute(sc, SA3_LCH, sc->master_mute);
127 1.2 augustss ym_mute(sc, SA3_RCH, sc->master_mute);
128 1.2 augustss
129 1.2 augustss sc->mic_mute = 1;
130 1.2 augustss ym_mute(sc, SA3_MIC, sc->mic_mute);
131 1.1 augustss
132 1.4 augustss audio_attach_mi(&ym_hw_if, &sc->sc_ad1848, &sc->sc_dev);
133 1.1 augustss }
134 1.1 augustss
135 1.1 augustss static __inline int
136 1.1 augustss ym_read(sc, reg)
137 1.2 augustss struct ym_softc *sc;
138 1.2 augustss int reg;
139 1.1 augustss {
140 1.2 augustss bus_space_write_1(sc->sc_iot, sc->sc_controlioh, 0, 0x1d);
141 1.2 augustss bus_space_write_1(sc->sc_iot, sc->sc_controlioh, 0, (reg & 0xff));
142 1.2 augustss return (bus_space_read_1(sc->sc_iot, sc->sc_controlioh, 1));
143 1.1 augustss }
144 1.1 augustss
145 1.1 augustss static __inline void
146 1.1 augustss ym_write(sc, reg, data)
147 1.2 augustss struct ym_softc *sc;
148 1.2 augustss int reg;
149 1.2 augustss int data;
150 1.1 augustss {
151 1.2 augustss bus_space_write_1(sc->sc_iot, sc->sc_controlioh, 0, 0x1d);
152 1.2 augustss bus_space_write_1(sc->sc_iot, sc->sc_controlioh, 0, (reg & 0xff));
153 1.2 augustss bus_space_write_1(sc->sc_iot, sc->sc_controlioh, 1, (data & 0xff));
154 1.1 augustss }
155 1.1 augustss
156 1.1 augustss
157 1.1 augustss
158 1.1 augustss int
159 1.1 augustss ym_getdev(addr, retp)
160 1.2 augustss void *addr;
161 1.2 augustss struct audio_device *retp;
162 1.1 augustss {
163 1.2 augustss *retp = ym_device;
164 1.2 augustss return 0;
165 1.1 augustss }
166 1.1 augustss
167 1.1 augustss
168 1.1 augustss static ad1848_devmap_t mappings[] = {
169 1.2 augustss { YM_MIDI_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
170 1.2 augustss { YM_CD_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
171 1.2 augustss { YM_DAC_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
172 1.2 augustss { YM_LINE_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL },
173 1.2 augustss { YM_SPEAKER_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
174 1.2 augustss { YM_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL },
175 1.2 augustss { YM_MIDI_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
176 1.2 augustss { YM_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
177 1.2 augustss { YM_DAC_MUTE, AD1848_KIND_MUTE, AD1848_DAC_CHANNEL },
178 1.2 augustss { YM_LINE_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL },
179 1.2 augustss { YM_SPEAKER_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
180 1.2 augustss { YM_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL },
181 1.2 augustss { YM_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
182 1.2 augustss { YM_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1}
183 1.1 augustss };
184 1.1 augustss
185 1.1 augustss static int nummap = sizeof(mappings) / sizeof(mappings[0]);
186 1.1 augustss
187 1.1 augustss
188 1.1 augustss static void
189 1.1 augustss ym_mute(sc, left_reg, mute)
190 1.2 augustss struct ym_softc *sc;
191 1.2 augustss int left_reg;
192 1.2 augustss int mute;
193 1.1 augustss
194 1.1 augustss {
195 1.2 augustss u_char reg;
196 1.1 augustss
197 1.2 augustss if (mute) {
198 1.2 augustss reg = ym_read(sc, left_reg);
199 1.2 augustss ym_write (sc, left_reg, reg | 0x80);
200 1.2 augustss } else {
201 1.2 augustss reg = ym_read(sc, left_reg);
202 1.2 augustss ym_write (sc, left_reg, reg & ~0x80);
203 1.2 augustss }
204 1.1 augustss }
205 1.1 augustss
206 1.1 augustss #define MIC_ATTEN_BITS 0x1f
207 1.1 augustss #define MASTER_ATTEN_BITS 0x0f
208 1.1 augustss
209 1.1 augustss
210 1.1 augustss static void
211 1.1 augustss ym_set_master_gain(sc, vol)
212 1.2 augustss struct ym_softc *sc;
213 1.2 augustss struct ad1848_volume *vol;
214 1.1 augustss {
215 1.2 augustss u_char reg;
216 1.2 augustss u_int atten;
217 1.2 augustss
218 1.2 augustss sc->master_gain = *vol;
219 1.2 augustss
220 1.2 augustss atten = ((AUDIO_MAX_GAIN - vol->left) * MASTER_ATTEN_BITS) /
221 1.2 augustss AUDIO_MAX_GAIN;
222 1.1 augustss
223 1.2 augustss reg = ym_read(sc, SA3_LCH);
224 1.1 augustss
225 1.2 augustss reg &= ~(MASTER_ATTEN_BITS);
226 1.2 augustss reg |= atten;
227 1.2 augustss
228 1.2 augustss ym_write (sc, SA3_LCH, reg);
229 1.2 augustss
230 1.2 augustss atten = ((AUDIO_MAX_GAIN - vol->right) * MASTER_ATTEN_BITS) /
231 1.2 augustss AUDIO_MAX_GAIN;
232 1.2 augustss
233 1.2 augustss reg = ym_read(sc, SA3_RCH) & ~(MASTER_ATTEN_BITS);
234 1.2 augustss reg |= atten;
235 1.2 augustss
236 1.2 augustss ym_write (sc, SA3_RCH, reg);
237 1.1 augustss }
238 1.1 augustss
239 1.1 augustss static void
240 1.1 augustss ym_set_mic_gain(sc, vol)
241 1.2 augustss struct ym_softc *sc;
242 1.2 augustss struct ad1848_volume *vol;
243 1.1 augustss {
244 1.2 augustss u_char reg;
245 1.2 augustss u_int atten;
246 1.2 augustss
247 1.2 augustss sc->mic_gain = *vol;
248 1.1 augustss
249 1.2 augustss atten = ((AUDIO_MAX_GAIN - vol->left) * MIC_ATTEN_BITS)/AUDIO_MAX_GAIN;
250 1.1 augustss
251 1.2 augustss reg = ym_read(sc, SA3_MIC) & ~(MIC_ATTEN_BITS);
252 1.2 augustss reg |= atten;
253 1.1 augustss
254 1.2 augustss ym_write (sc, SA3_MIC, reg);
255 1.1 augustss }
256 1.1 augustss
257 1.1 augustss int
258 1.1 augustss ym_mixer_set_port(addr, cp)
259 1.2 augustss void *addr;
260 1.2 augustss mixer_ctrl_t *cp;
261 1.1 augustss {
262 1.2 augustss struct ad1848_softc *ac = addr;
263 1.2 augustss struct ym_softc *sc = ac->parent;
264 1.2 augustss struct ad1848_volume vol;
265 1.2 augustss int error = ad1848_mixer_set_port(ac, mappings, nummap, cp);
266 1.1 augustss
267 1.2 augustss if (error != ENXIO)
268 1.2 augustss return (error);
269 1.1 augustss
270 1.2 augustss error = 0;
271 1.1 augustss
272 1.2 augustss switch (cp->dev) {
273 1.2 augustss case YM_OUTPUT_LVL:
274 1.2 augustss ad1848_to_vol(cp, &vol);
275 1.2 augustss ym_set_master_gain(sc, &vol);
276 1.2 augustss break;
277 1.2 augustss
278 1.2 augustss case YM_OUTPUT_MUTE:
279 1.2 augustss sc->master_mute = (cp->un.ord != 0);
280 1.2 augustss ym_mute(sc, SA3_LCH, sc->master_mute);
281 1.2 augustss ym_mute(sc, SA3_RCH, sc->master_mute);
282 1.2 augustss break;
283 1.2 augustss
284 1.2 augustss case YM_MIC_LVL:
285 1.2 augustss if (cp->un.value.num_channels != 1)
286 1.2 augustss error = EINVAL;
287 1.2 augustss
288 1.2 augustss ad1848_to_vol(cp, &vol);
289 1.2 augustss ym_set_mic_gain(sc, &vol);
290 1.2 augustss break;
291 1.2 augustss
292 1.2 augustss case YM_MIC_MUTE:
293 1.2 augustss sc->mic_mute = (cp->un.ord != 0);
294 1.2 augustss ym_mute(sc, SA3_MIC, sc->mic_mute);
295 1.2 augustss break;
296 1.2 augustss
297 1.2 augustss default:
298 1.2 augustss return ENXIO;
299 1.2 augustss /*NOTREACHED*/
300 1.2 augustss }
301 1.1 augustss
302 1.2 augustss return (error);
303 1.1 augustss }
304 1.1 augustss
305 1.1 augustss int
306 1.1 augustss ym_mixer_get_port(addr, cp)
307 1.2 augustss void *addr;
308 1.2 augustss mixer_ctrl_t *cp;
309 1.1 augustss {
310 1.2 augustss struct ad1848_softc *ac = addr;
311 1.2 augustss struct ym_softc *sc = ac->parent;
312 1.2 augustss
313 1.2 augustss int error = ad1848_mixer_get_port(ac, mappings, nummap, cp);
314 1.2 augustss
315 1.2 augustss if (error != ENXIO)
316 1.2 augustss return (error);
317 1.2 augustss
318 1.2 augustss error = 0;
319 1.1 augustss
320 1.2 augustss switch (cp->dev) {
321 1.2 augustss case YM_OUTPUT_LVL:
322 1.2 augustss ad1848_from_vol(cp, &sc->master_gain);
323 1.2 augustss break;
324 1.2 augustss
325 1.2 augustss case YM_OUTPUT_MUTE:
326 1.2 augustss cp->un.ord = sc->master_mute;
327 1.2 augustss break;
328 1.2 augustss
329 1.2 augustss case YM_MIC_LVL:
330 1.2 augustss if (cp->un.value.num_channels != 1)
331 1.2 augustss error = EINVAL;
332 1.2 augustss ad1848_from_vol(cp, &sc->mic_gain);
333 1.2 augustss break;
334 1.2 augustss
335 1.2 augustss case YM_MIC_MUTE:
336 1.2 augustss cp->un.ord = sc->mic_mute;
337 1.2 augustss break;
338 1.2 augustss
339 1.2 augustss default:
340 1.2 augustss error = ENXIO;
341 1.2 augustss break;
342 1.2 augustss }
343 1.2 augustss
344 1.2 augustss return(error);
345 1.1 augustss }
346 1.1 augustss
347 1.2 augustss static char *mixer_classes[] =
348 1.2 augustss { AudioCinputs, AudioCrecord, AudioCoutputs, AudioCmonitor };
349 1.1 augustss
350 1.1 augustss int
351 1.1 augustss ym_query_devinfo(addr, dip)
352 1.2 augustss void *addr;
353 1.2 augustss mixer_devinfo_t *dip;
354 1.1 augustss {
355 1.2 augustss static char *mixer_port_names[] =
356 1.2 augustss { AudioNmidi, AudioNcd, AudioNdac, AudioNline, AudioNspeaker,
357 1.2 augustss AudioNmicrophone, AudioNmonitor};
358 1.1 augustss
359 1.2 augustss dip->next = dip->prev = AUDIO_MIXER_LAST;
360 1.2 augustss
361 1.2 augustss switch(dip->index) {
362 1.2 augustss case YM_INPUT_CLASS: /* input class descriptor */
363 1.2 augustss case YM_OUTPUT_CLASS:
364 1.2 augustss case YM_MONITOR_CLASS:
365 1.2 augustss case YM_RECORD_CLASS:
366 1.2 augustss dip->type = AUDIO_MIXER_CLASS;
367 1.2 augustss dip->mixer_class = dip->index;
368 1.2 augustss strcpy(dip->label.name,
369 1.2 augustss mixer_classes[dip->index - YM_INPUT_CLASS]);
370 1.2 augustss break;
371 1.2 augustss
372 1.2 augustss case YM_MIDI_LVL:
373 1.2 augustss case YM_CD_LVL:
374 1.2 augustss case YM_DAC_LVL:
375 1.2 augustss case YM_LINE_LVL:
376 1.2 augustss case YM_SPEAKER_LVL:
377 1.2 augustss case YM_MIC_LVL:
378 1.2 augustss case YM_MONITOR_LVL:
379 1.2 augustss dip->type = AUDIO_MIXER_VALUE;
380 1.2 augustss if (dip->index == YM_MONITOR_LVL)
381 1.2 augustss dip->mixer_class = YM_MONITOR_CLASS;
382 1.2 augustss else
383 1.2 augustss dip->mixer_class = YM_INPUT_CLASS;
384 1.2 augustss
385 1.2 augustss dip->next = dip->index + 7;
386 1.2 augustss
387 1.2 augustss strcpy(dip->label.name,
388 1.2 augustss mixer_port_names[dip->index - YM_MIDI_LVL]);
389 1.2 augustss
390 1.2 augustss if (dip->index == YM_SPEAKER_LVL ||
391 1.2 augustss dip->index == YM_MIC_LVL)
392 1.2 augustss dip->un.v.num_channels = 1;
393 1.2 augustss else
394 1.2 augustss dip->un.v.num_channels = 2;
395 1.2 augustss
396 1.2 augustss strcpy(dip->un.v.units.name, AudioNvolume);
397 1.2 augustss break;
398 1.2 augustss
399 1.2 augustss case YM_MIDI_MUTE:
400 1.2 augustss case YM_CD_MUTE:
401 1.2 augustss case YM_DAC_MUTE:
402 1.2 augustss case YM_LINE_MUTE:
403 1.2 augustss case YM_SPEAKER_MUTE:
404 1.2 augustss case YM_MIC_MUTE:
405 1.2 augustss case YM_MONITOR_MUTE:
406 1.2 augustss if (dip->index == YM_MONITOR_MUTE)
407 1.2 augustss dip->mixer_class = YM_MONITOR_CLASS;
408 1.2 augustss else
409 1.2 augustss dip->mixer_class = YM_INPUT_CLASS;
410 1.2 augustss dip->type = AUDIO_MIXER_ENUM;
411 1.2 augustss dip->prev = dip->index - 7;
412 1.2 augustss mute:
413 1.2 augustss strcpy(dip->label.name, AudioNmute);
414 1.2 augustss dip->un.e.num_mem = 2;
415 1.2 augustss strcpy(dip->un.e.member[0].label.name, AudioNoff);
416 1.2 augustss dip->un.e.member[0].ord = 0;
417 1.2 augustss strcpy(dip->un.e.member[1].label.name, AudioNon);
418 1.2 augustss dip->un.e.member[1].ord = 1;
419 1.2 augustss break;
420 1.2 augustss
421 1.2 augustss
422 1.2 augustss case YM_OUTPUT_LVL:
423 1.2 augustss dip->type = AUDIO_MIXER_VALUE;
424 1.2 augustss dip->mixer_class = YM_OUTPUT_CLASS;
425 1.2 augustss dip->next = YM_OUTPUT_MUTE;
426 1.2 augustss strcpy(dip->label.name, AudioNmaster);
427 1.2 augustss dip->un.v.num_channels = 2;
428 1.2 augustss strcpy(dip->un.v.units.name, AudioNvolume);
429 1.2 augustss break;
430 1.2 augustss
431 1.2 augustss case YM_OUTPUT_MUTE:
432 1.2 augustss dip->mixer_class = YM_OUTPUT_CLASS;
433 1.2 augustss dip->type = AUDIO_MIXER_ENUM;
434 1.2 augustss dip->prev = YM_OUTPUT_LVL;
435 1.2 augustss goto mute;
436 1.2 augustss
437 1.2 augustss case YM_REC_LVL: /* record level */
438 1.2 augustss dip->type = AUDIO_MIXER_VALUE;
439 1.2 augustss dip->mixer_class = YM_RECORD_CLASS;
440 1.2 augustss dip->next = YM_RECORD_SOURCE;
441 1.2 augustss strcpy(dip->label.name, AudioNrecord);
442 1.2 augustss dip->un.v.num_channels = 2;
443 1.2 augustss strcpy(dip->un.v.units.name, AudioNvolume);
444 1.2 augustss break;
445 1.2 augustss
446 1.2 augustss
447 1.2 augustss case YM_RECORD_SOURCE:
448 1.2 augustss dip->mixer_class = YM_RECORD_CLASS;
449 1.2 augustss dip->type = AUDIO_MIXER_ENUM;
450 1.2 augustss dip->prev = YM_REC_LVL;
451 1.2 augustss strcpy(dip->label.name, AudioNsource);
452 1.2 augustss dip->un.e.num_mem = 4;
453 1.2 augustss strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
454 1.2 augustss dip->un.e.member[0].ord = MIC_IN_PORT;
455 1.2 augustss strcpy(dip->un.e.member[1].label.name, AudioNline);
456 1.2 augustss dip->un.e.member[1].ord = LINE_IN_PORT;
457 1.2 augustss strcpy(dip->un.e.member[2].label.name, AudioNdac);
458 1.2 augustss dip->un.e.member[2].ord = DAC_IN_PORT;
459 1.2 augustss strcpy(dip->un.e.member[3].label.name, AudioNcd);
460 1.2 augustss dip->un.e.member[3].ord = AUX1_IN_PORT;
461 1.2 augustss break;
462 1.2 augustss
463 1.2 augustss default:
464 1.2 augustss return ENXIO;
465 1.2 augustss /*NOTREACHED*/
466 1.2 augustss }
467 1.2 augustss
468 1.2 augustss return 0;
469 1.1 augustss }
470