uda1341.c revision 1.1.56.1 1 /*-
2 * Copyright (c) 2012 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Paul Fleischer <paul (at) xpg.dk>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <sys/cdefs.h>
31
32 #include <sys/param.h>
33 #include <sys/device.h>
34 #include <sys/audioio.h>
35 #include <sys/fcntl.h>
36
37 #include <dev/audio_if.h>
38
39 #include <dev/ic/uda1341var.h>
40 #include <dev/ic/uda1341reg.h>
41
42 /*#define UDA1341_DEBUG*/
43
44 #ifdef UDA1341_DEBUG
45 #define DPRINTF(x) do {printf x; } while (/*CONSTCOND*/0)
46 #else
47 #define DPRINTF(s) do {} while (/*CONSTCOND*/0)
48 #endif
49
50 #define UDA1341_FORMAT(enc, prec) \
51 { \
52 .mode = AUMODE_PLAY | AUMODE_RECORD, \
53 .encoding = (enc), \
54 .validbits = (prec), \
55 .precision = (prec), \
56 .channels = 2, \
57 .channel_mask = AUFMT_STEREO, \
58 .frequency_type = 0, \
59 .frequency = { 8000, 48000 }, \
60 }
61 const struct audio_format uda1341_formats[UDA1341_NFORMATS] =
62 {
63 UDA1341_FORMAT(AUDIO_ENCODING_SLINEAR_LE, 8),
64 UDA1341_FORMAT(AUDIO_ENCODING_SLINEAR_LE, 16),
65 UDA1341_FORMAT(AUDIO_ENCODING_ULINEAR_LE, 8),
66 UDA1341_FORMAT(AUDIO_ENCODING_ULINEAR_LE, 16),
67 };
68
69 static void uda1341_update_sound_settings(struct uda1341_softc *sc);
70
71
72 int
73 uda1341_attach(struct uda1341_softc *sc)
74 {
75 sc->sc_system_clock = UDA1341_CLOCK_NA;
76 sc->sc_l3_write = NULL;
77 sc->sc_volume = 127;
78 sc->sc_bass = 0;
79 sc->sc_treble = 0;
80 sc->sc_mode = 0;
81 sc->sc_mute = 0;
82 sc->sc_ogain = 0;
83 sc->sc_deemphasis = UDA1341_DEEMPHASIS_AUTO;
84 sc->sc_dac_power = 0;
85 sc->sc_adc_power = 0;
86 sc->sc_inmix1 = 0;
87 sc->sc_inmix2 = 0;
88 sc->sc_micvol = 0;
89 sc->sc_inmode = 0;
90 sc->sc_agc = 0;
91 sc->sc_agc_lvl = 0;
92 sc->sc_ch2_gain = 0;
93
94 return 0;
95 }
96
97 int
98 uda1341_query_encodings(void *handle, audio_encoding_t *ae)
99 {
100 switch(ae->index) {
101 case 0:
102 strlcpy(ae->name, AudioEmulaw, sizeof(ae->name));
103 ae->encoding = AUDIO_ENCODING_ULAW;
104 ae->precision = 8;
105 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
106 break;
107 case 1:
108 strlcpy(ae->name, AudioEslinear_le, sizeof(ae->name));
109 ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
110 ae->precision = 8;
111 ae->flags = 0;
112 break;
113 case 2:
114 strlcpy(ae->name, AudioEslinear_le, sizeof(ae->name));
115 ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
116 ae->precision = 16;
117 ae->flags = 0;
118 break;
119 case 3:
120 strlcpy(ae->name, AudioEulinear_le, sizeof(ae->name));
121 ae->encoding = AUDIO_ENCODING_ULINEAR_LE;
122 ae->precision = 8;
123 ae->flags = 0;
124 break;
125 case 4:
126 strlcpy(ae->name, AudioEulinear_le, sizeof(ae->name));
127 ae->encoding = AUDIO_ENCODING_ULINEAR_LE;
128 ae->precision = 16;
129 ae->flags = 0;
130 break;
131
132 default:
133 return EINVAL;
134 }
135
136 return 0;
137 }
138
139 int
140 uda1341_open(void *handle, int flags)
141 {
142 struct uda1341_softc *sc = handle;
143
144 /* Reset the UDA1341 */
145 sc->sc_l3_write(sc, 0, UDA1341_L3_ADDR_DEVICE |
146 UDA1341_L3_ADDR_STATUS);
147 sc->sc_l3_write(sc, 1,
148 UDA1341_L3_STATUS0 |
149 UDA1341_L3_STATUS0_RST);
150
151 if (flags & FREAD) {
152 sc->sc_adc_power = 1;
153 }
154 if (flags & FWRITE) {
155 sc->sc_dac_power = 1;
156 }
157
158 #if 0
159 /* Power on DAC */
160 sc->sc_l3_write(sc, 1,
161 UDA1341_L3_STATUS1 | UDA1341_L3_STATUS1_PC_DAC);
162 #endif
163 uda1341_update_sound_settings(sc);
164
165 #if 0
166 /* TODO: Add mixer support */
167 sc->sc_l3_write(sc, 0, 0x14 | 0x0);
168 sc->sc_l3_write(sc, 1, 0x15); /* Volume */
169 #endif
170
171 return 0;
172 }
173
174 void
175 uda1341_close(void *handle)
176 {
177 struct uda1341_softc *sc = handle;
178 /* Reset the UDA1341 */
179 sc->sc_l3_write(sc, 0, UDA1341_L3_ADDR_DEVICE |
180 UDA1341_L3_ADDR_STATUS);
181
182 /* Power off DAC and ADC*/
183 sc->sc_l3_write(sc, 1,
184 UDA1341_L3_STATUS1);
185
186 sc->sc_dac_power = 0;
187 sc->sc_adc_power = 0;
188 }
189
190 int
191 uda1341_set_params(void *handle, int setmode, int usemode,
192 audio_params_t *play, audio_params_t *rec,
193 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
194 {
195 struct uda1341_softc *sc = handle;
196 if (sc->sc_system_clock == UDA1341_CLOCK_NA)
197 panic("uda1341_set_params was called without sc_system_clock set!\n");
198
199 /* Select status register */
200 sc->sc_l3_write(sc, 0, UDA1341_L3_ADDR_DEVICE |
201 UDA1341_L3_ADDR_STATUS);
202
203 sc->sc_l3_write(sc, 1, UDA1341_L3_STATUS0 |
204 sc->sc_system_clock << UDA1341_L3_STATUS0_SC_SHIFT |
205 sc->sc_bus_format << UDA1341_L3_STATUS0_IF_SHIFT
206 );
207
208 if (sc->sc_sample_rate_approx != play->sample_rate) {
209 sc->sc_sample_rate_approx = play->sample_rate;
210 uda1341_update_sound_settings(sc);
211 }
212
213 return 0;
214 }
215
216 #define AUDIO_LEVELS (AUDIO_MAX_GAIN-AUDIO_MIN_GAIN+1)
217 static void
218 uda1341_update_sound_settings(struct uda1341_softc *sc)
219 {
220 /* TODO: Refactor this function into smaller parts, such that
221 * a volume change does not trigger updates of all the
222 * other -- unrelated -- registers.
223 */
224
225 uint8_t val, volume, bass, treble, deemphasis;
226
227 sc->sc_l3_write(sc, 0, UDA1341_L3_ADDR_DEVICE | UDA1341_L3_ADDR_STATUS);
228 val = UDA1341_L3_STATUS1;
229 if (sc->sc_dac_power)
230 val |= UDA1341_L3_STATUS1_PC_DAC;
231 if (sc->sc_adc_power)
232 val |= UDA1341_L3_STATUS1_PC_ADC;
233 if (sc->sc_ogain)
234 val |= UDA1341_L3_STATUS1_OGS_6DB;
235
236 sc->sc_l3_write(sc, 1, val);
237
238 sc->sc_l3_write(sc, 0, UDA1341_L3_ADDR_DEVICE | UDA1341_L3_ADDR_DATA0);
239
240 /* Update volume */
241 /* On the UDA1341 maximal volume is 0x0,
242 while minimal volume is 0x3f */
243 volume = (0x3f) - ((sc->sc_volume*(0x3f+1)) / (AUDIO_LEVELS));
244
245 val = UDA1341_L3_DATA0_VOLUME;
246 val |= volume & UDA1341_L3_DATA0_VOLUME_MASK;
247 sc->sc_l3_write(sc, 1, val);
248
249 /* Update bass and treble */
250 bass = (sc->sc_bass*(0xf+1)) / AUDIO_LEVELS;
251 treble = (sc->sc_treble*(0x3+1)) / AUDIO_LEVELS;
252 val = UDA1341_L3_DATA0_BASS_TREBLE;
253 val |= (bass << UDA1341_L3_DATA0_BASS_SHIFT) &
254 UDA1341_L3_DATA0_BASS_MASK;
255 val |= (treble << UDA1341_L3_DATA0_TREBLE_SHIFT) &
256 UDA1341_L3_DATA0_TREBLE_MASK;
257 sc->sc_l3_write(sc, 1, val);
258
259 /* Update the remaining output sound controls:
260 * - Peak-detect position
261 * - De-emphasis
262 * - Mute
263 * - Mode Switch
264 * XXX: Only Mode-switch, de-emphasis, and mute is currently supported.
265 */
266 val = UDA1341_L3_DATA0_SOUNDC;
267
268 deemphasis = sc->sc_deemphasis;
269 if( deemphasis == UDA1341_DEEMPHASIS_AUTO) {
270 /* Set deemphasis according to current sample rate */
271 switch (sc->sc_sample_rate_approx) {
272 case 32000:
273 deemphasis = 0x1;
274 break;
275 case 44100:
276 deemphasis = 0x2;
277 break;
278 case 48000:
279 deemphasis = 0x3;
280 break;
281 default:
282 deemphasis = 0x0;
283 }
284 }
285
286 DPRINTF(("Deemphasis: %d\n", deemphasis));
287 val |= (deemphasis << UDA1341_L3_DATA0_SOUNDC_DE_SHIFT) &
288 UDA1341_L3_DATA0_SOUNDC_DE_MASK;
289
290 if (sc->sc_mute)
291 val |= UDA1341_L3_DATA0_SOUNDC_MUTE;
292 val |= sc->sc_mode & UDA1341_L3_DATA0_SOUNDC_MODE_MASK;
293 sc->sc_l3_write(sc, 1, val);
294
295 /* Extended Register 0: MA */
296 val = UDA1341_L3_DATA0_ED;
297 val |= (sc->sc_inmix1 & UDA1341_L3_DATA0_MA_MASK);
298 sc->sc_l3_write(sc, 1, UDA1341_L3_DATA0_EA | 0x0);
299 sc->sc_l3_write(sc, 1, val);
300
301 /* Extended Register 1: MB */
302 val = UDA1341_L3_DATA0_ED;
303 val |= (sc->sc_inmix2 & UDA1341_L3_DATA0_MB_MASK);
304 sc->sc_l3_write(sc, 1, UDA1341_L3_DATA0_EA | 0x01);
305 sc->sc_l3_write(sc, 1, val);
306
307 /* Extended Register 2: MIC sensitivity and mixer mode */
308 val = UDA1341_L3_DATA0_ED;
309 val |= (sc->sc_micvol << UDA1341_L3_DATA0_MS_SHIFT) &
310 UDA1341_L3_DATA0_MS_MASK;
311 val |= sc->sc_inmode & UDA1341_L3_DATA0_MM_MASK;
312 sc->sc_l3_write(sc, 1, UDA1341_L3_DATA0_EA | 0x02);
313 sc->sc_l3_write(sc, 1, val);
314
315 /* Extended Register 4: AGC and IG (ch2_gain) */
316 val = UDA1341_L3_DATA0_ED;
317
318 val |= (sc->sc_agc << UDA1341_L3_DATA0_AGC_SHIFT) &
319 UDA1341_L3_DATA0_AGC_MASK;
320 val |= (sc->sc_ch2_gain & 0x03) & UDA1341_L3_DATA0_IG_LOW_MASK;
321 sc->sc_l3_write(sc, 1, UDA1341_L3_DATA0_EA | 0x04);
322 sc->sc_l3_write(sc, 1, val);
323
324 /* Extended Register 5: IG (ch2_gain) */
325 val = UDA1341_L3_DATA0_ED;
326 val |= (sc->sc_ch2_gain >> 2 ) & UDA1341_L3_DATA0_IG_HIGH_MASK;
327 sc->sc_l3_write(sc, 1, UDA1341_L3_DATA0_EA | 0x05);
328 sc->sc_l3_write(sc, 1, val);
329
330 /* Extended Register 6: AT and AL */
331 /* XXX: Only AL is supported at this point */
332 val = UDA1341_L3_DATA0_ED;
333 val |= sc->sc_agc_lvl & UDA1341_L3_DATA0_AL_MASK;
334 sc->sc_l3_write(sc, 1, UDA1341_L3_DATA0_EA | 0x06);
335 sc->sc_l3_write(sc, 1, val);
336 }
337
338 #define UDA1341_MIXER_VOL 0
339 #define UDA1341_MIXER_BASS 1
340 #define UDA1341_MIXER_TREBLE 2
341 #define UDA1341_MIXER_MODE 3
342 #define UDA1341_MIXER_MUTE 4
343 #define UDA1341_MIXER_OGAIN 5
344 #define UDA1341_MIXER_DE 6
345 #define UDA1341_OUTPUT_CLASS 7
346
347 #define UDA1341_MIXER_INMIX1 8
348 #define UDA1341_MIXER_INMIX2 9
349 #define UDA1341_MIXER_MICVOL 10
350 #define UDA1341_MIXER_INMODE 11
351 #define UDA1341_MIXER_AGC 12
352 #define UDA1341_MIXER_AGC_LVL 13
353 #define UDA1341_MIXER_IN_GAIN2 14
354 /*#define UDA1341_MIXER_AGC_SETTINGS 15*/
355 #define UDA1341_INPUT_CLASS 15
356
357 int
358 uda1341_query_devinfo(void *handle, mixer_devinfo_t *mi)
359 {
360
361 switch(mi->index) {
362 case UDA1341_MIXER_VOL:
363 strlcpy(mi->label.name, AudioNspeaker,
364 sizeof(mi->label.name));
365 mi->type = AUDIO_MIXER_VALUE;
366 mi->mixer_class = UDA1341_OUTPUT_CLASS;
367 mi->next = UDA1341_MIXER_BASS;
368 mi->prev = AUDIO_MIXER_LAST;
369 strlcpy(mi->un.v.units.name, AudioNvolume,
370 sizeof(mi->un.v.units.name));
371 mi->un.v.num_channels = 1;
372 mi->un.v.delta = 256/64;
373 break;
374 case UDA1341_MIXER_BASS:
375 strlcpy(mi->label.name, AudioNbass,
376 sizeof(mi->label.name));
377 mi->type = AUDIO_MIXER_VALUE;
378 mi->mixer_class = UDA1341_OUTPUT_CLASS;
379 mi->next = UDA1341_MIXER_TREBLE;
380 mi->prev = UDA1341_MIXER_VOL;
381 strlcpy(mi->un.v.units.name, AudioNbass,
382 sizeof(mi->un.v.units.name));
383 mi->un.v.num_channels = 1;
384 mi->un.v.delta = 256/16;
385 break;
386 case UDA1341_MIXER_TREBLE:
387 strlcpy(mi->label.name, AudioNtreble,
388 sizeof(mi->label.name));
389 mi->type = AUDIO_MIXER_VALUE;
390 mi->mixer_class = UDA1341_OUTPUT_CLASS;
391 mi->next = UDA1341_MIXER_MODE;
392 mi->prev = UDA1341_MIXER_BASS;
393 strlcpy(mi->un.v.units.name, AudioNtreble,
394 sizeof(mi->un.v.units.name));
395 mi->un.v.num_channels = 1;
396 mi->un.v.delta = 256/4;
397 break;
398 case UDA1341_MIXER_MODE:
399 strlcpy(mi->label.name, AudioNmode,
400 sizeof(mi->label.name));
401 mi->type = AUDIO_MIXER_ENUM;
402 mi->mixer_class = UDA1341_OUTPUT_CLASS;
403 mi->next = UDA1341_MIXER_MUTE;
404 mi->prev = UDA1341_MIXER_TREBLE;
405 mi->un.e.num_mem = 3;
406
407 strlcpy(mi->un.e.member[0].label.name,
408 "flat", sizeof(mi->un.e.member[0].label.name));
409 mi->un.e.member[0].ord = 0;
410
411 strlcpy(mi->un.e.member[1].label.name,
412 "minimum", sizeof(mi->un.e.member[1].label.name));
413 mi->un.e.member[1].ord = 1;
414
415 strlcpy(mi->un.e.member[2].label.name,
416 "maximum", sizeof(mi->un.e.member[2].label.name));
417 mi->un.e.member[2].ord = 3;
418
419 break;
420 case UDA1341_MIXER_MUTE:
421 strlcpy(mi->label.name, AudioNmute,
422 sizeof(mi->label.name));
423 mi->type = AUDIO_MIXER_ENUM;
424 mi->mixer_class = UDA1341_OUTPUT_CLASS;
425 mi->next = UDA1341_MIXER_OGAIN;
426 mi->prev = UDA1341_MIXER_MODE;
427 mi->un.e.num_mem = 2;
428
429 strlcpy(mi->un.e.member[0].label.name,
430 "off", sizeof(mi->un.e.member[0].label.name));
431 mi->un.e.member[0].ord = 0;
432
433 strlcpy(mi->un.e.member[1].label.name,
434 "on", sizeof(mi->un.e.member[1].label.name));
435 mi->un.e.member[1].ord = 1;
436 break;
437 case UDA1341_MIXER_OGAIN:
438 strlcpy(mi->label.name, "gain",
439 sizeof(mi->label.name));
440 mi->type = AUDIO_MIXER_ENUM;
441 mi->mixer_class = UDA1341_OUTPUT_CLASS;
442 mi->next = UDA1341_MIXER_DE;
443 mi->prev = UDA1341_MIXER_MUTE;
444 mi->un.e.num_mem = 2;
445
446 strlcpy(mi->un.e.member[0].label.name,
447 "off", sizeof(mi->un.e.member[0].label.name));
448 mi->un.e.member[0].ord = 0;
449
450 strlcpy(mi->un.e.member[1].label.name,
451 "on", sizeof(mi->un.e.member[1].label.name));
452 mi->un.e.member[1].ord = 1;
453 break;
454 case UDA1341_MIXER_DE:
455 strlcpy(mi->label.name, "deemphasis",
456 sizeof(mi->label.name));
457 mi->type = AUDIO_MIXER_ENUM;
458 mi->mixer_class = UDA1341_OUTPUT_CLASS;
459 mi->next = AUDIO_MIXER_LAST;
460 mi->prev = UDA1341_MIXER_OGAIN;
461 mi->un.e.num_mem = 5;
462
463 strlcpy(mi->un.e.member[0].label.name,
464 "none", sizeof(mi->un.e.member[0].label.name));
465 mi->un.e.member[0].ord = 0;
466
467 strlcpy(mi->un.e.member[1].label.name,
468 "32KHz", sizeof(mi->un.e.member[1].label.name));
469 mi->un.e.member[1].ord = 1;
470
471 strlcpy(mi->un.e.member[2].label.name,
472 "44.1KHz", sizeof(mi->un.e.member[2].label.name));
473 mi->un.e.member[2].ord = 2;
474
475 strlcpy(mi->un.e.member[3].label.name,
476 "48KHz", sizeof(mi->un.e.member[3].label.name));
477 mi->un.e.member[3].ord = 3;
478
479 strlcpy(mi->un.e.member[4].label.name,
480 "auto", sizeof(mi->un.e.member[4].label.name));
481 mi->un.e.member[4].ord = 4;
482
483 break;
484 case UDA1341_OUTPUT_CLASS:
485 mi->type = AUDIO_MIXER_CLASS;
486 mi->mixer_class = UDA1341_OUTPUT_CLASS;
487 mi->prev = AUDIO_MIXER_LAST;
488 mi->next = AUDIO_MIXER_LAST;
489 strlcpy(mi->label.name, AudioCoutputs,
490 sizeof(mi->label.name));
491 break;
492 case UDA1341_MIXER_INMIX1:
493 strlcpy(mi->label.name, "inmix1",
494 sizeof(mi->label.name));
495 mi->type = AUDIO_MIXER_VALUE;
496 mi->mixer_class = UDA1341_INPUT_CLASS;
497 mi->next = AUDIO_MIXER_LAST;
498 mi->prev = AUDIO_MIXER_LAST;
499 strlcpy(mi->un.v.units.name, AudioNvolume,
500 sizeof(mi->un.v.units.name));
501 mi->un.v.num_channels = 1;
502 mi->un.v.delta = 256/64;
503 break;
504 case UDA1341_MIXER_INMIX2:
505 strlcpy(mi->label.name, "inmix2",
506 sizeof(mi->label.name));
507 mi->type = AUDIO_MIXER_VALUE;
508 mi->mixer_class = UDA1341_INPUT_CLASS;
509 mi->next = AUDIO_MIXER_LAST;
510 mi->prev = AUDIO_MIXER_LAST;
511 strlcpy(mi->un.v.units.name, AudioNvolume,
512 sizeof(mi->un.v.units.name));
513 mi->un.v.num_channels = 1;
514 mi->un.v.delta = 256/64;
515 break;
516 case UDA1341_MIXER_MICVOL:
517 strlcpy(mi->label.name, AudioNmicrophone,
518 sizeof(mi->label.name));
519 mi->type = AUDIO_MIXER_VALUE;
520 mi->mixer_class = UDA1341_INPUT_CLASS;
521 mi->next = AUDIO_MIXER_LAST;
522 mi->prev = AUDIO_MIXER_LAST;
523 strlcpy(mi->un.v.units.name, AudioNvolume,
524 sizeof(mi->un.v.units.name));
525 mi->un.v.num_channels = 1;
526 mi->un.v.delta = 256/8;
527 break;
528 case UDA1341_MIXER_INMODE:
529 strlcpy(mi->label.name, "inmode",
530 sizeof(mi->label.name));
531 mi->type = AUDIO_MIXER_ENUM;
532 mi->mixer_class = UDA1341_INPUT_CLASS;
533 mi->next = AUDIO_MIXER_LAST;
534 mi->prev = AUDIO_MIXER_LAST;
535 mi->un.e.num_mem = 4;
536
537 strlcpy(mi->un.e.member[0].label.name,
538 "dd", sizeof(mi->un.e.member[0].label.name));
539 mi->un.e.member[0].ord = 0;
540
541 strlcpy(mi->un.e.member[1].label.name,
542 "ch1", sizeof(mi->un.e.member[1].label.name));
543 mi->un.e.member[1].ord = 1;
544
545 strlcpy(mi->un.e.member[2].label.name,
546 "ch2", sizeof(mi->un.e.member[2].label.name));
547 mi->un.e.member[2].ord = 2;
548
549 strlcpy(mi->un.e.member[3].label.name,
550 "mix", sizeof(mi->un.e.member[3].label.name));
551 mi->un.e.member[3].ord = 3;
552 break;
553 case UDA1341_MIXER_AGC:
554 strlcpy(mi->label.name, "agc",
555 sizeof(mi->label.name));
556 mi->type = AUDIO_MIXER_ENUM;
557 mi->mixer_class = UDA1341_INPUT_CLASS;
558 mi->next = AUDIO_MIXER_LAST;
559 mi->prev = AUDIO_MIXER_LAST;
560 mi->un.e.num_mem = 2;
561
562 strlcpy(mi->un.e.member[0].label.name,
563 "off", sizeof(mi->un.e.member[0].label.name));
564 mi->un.e.member[0].ord = 0;
565
566 strlcpy(mi->un.e.member[1].label.name,
567 "on", sizeof(mi->un.e.member[1].label.name));
568 mi->un.e.member[1].ord = 1;
569 break;
570 case UDA1341_MIXER_AGC_LVL:
571 strlcpy(mi->label.name, "agclevel",
572 sizeof(mi->label.name));
573 mi->type = AUDIO_MIXER_VALUE;
574 mi->mixer_class = UDA1341_INPUT_CLASS;
575 mi->next = AUDIO_MIXER_LAST;
576 mi->prev = AUDIO_MIXER_LAST;
577 strlcpy(mi->un.v.units.name, AudioNvolume,
578 sizeof(mi->un.v.units.name));
579 mi->un.v.num_channels = 1;
580 mi->un.v.delta = 256/4;
581 break;
582 case UDA1341_MIXER_IN_GAIN2:
583 strlcpy(mi->label.name, "ch2gain",
584 sizeof(mi->label.name));
585 mi->type = AUDIO_MIXER_VALUE;
586 mi->mixer_class = UDA1341_INPUT_CLASS;
587 mi->next = AUDIO_MIXER_LAST;
588 mi->prev = AUDIO_MIXER_LAST;
589 strlcpy(mi->un.v.units.name, AudioNvolume,
590 sizeof(mi->un.v.units.name));
591 mi->un.v.num_channels = 1;
592 mi->un.v.delta = 256/128;
593 break;
594 case UDA1341_INPUT_CLASS:
595 mi->type = AUDIO_MIXER_CLASS;
596 mi->mixer_class = UDA1341_INPUT_CLASS;
597 mi->prev = AUDIO_MIXER_LAST;
598 mi->next = AUDIO_MIXER_LAST;
599 strlcpy(mi->label.name, AudioCinputs,
600 sizeof(mi->label.name));
601 break;
602 default:
603 return ENXIO;
604 }
605
606 return 0;
607 }
608
609 int
610 uda1341_get_port(void *handle, mixer_ctrl_t *mixer)
611 {
612 struct uda1341_softc *sc = handle;
613
614 switch(mixer->dev) {
615 case UDA1341_MIXER_VOL:
616 if (mixer->type != AUDIO_MIXER_VALUE)
617 return EINVAL;
618 if (mixer->un.value.num_channels != 1)
619 return EINVAL;
620 mixer->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
621 sc->sc_volume;
622 break;
623 case UDA1341_MIXER_BASS:
624 if (mixer->type != AUDIO_MIXER_VALUE ||
625 mixer->un.value.num_channels != 1)
626 return EINVAL;
627
628 mixer->un.value.level[0] = sc->sc_bass;
629 break;
630 case UDA1341_MIXER_TREBLE:
631 if (mixer->type != AUDIO_MIXER_VALUE ||
632 mixer->un.value.num_channels != 1)
633 return EINVAL;
634
635 mixer->un.value.level[0] = sc->sc_treble;
636 break;
637 case UDA1341_MIXER_MODE:
638 if (mixer->type != AUDIO_MIXER_ENUM)
639 return EINVAL;
640
641 mixer->un.ord = sc->sc_mode;
642 break;
643 case UDA1341_MIXER_MUTE:
644 if (mixer->type != AUDIO_MIXER_ENUM)
645 return EINVAL;
646
647 mixer->un.ord = sc->sc_mute;
648 break;
649 case UDA1341_MIXER_OGAIN:
650 if (mixer->type != AUDIO_MIXER_ENUM)
651 return EINVAL;
652
653 mixer->un.ord = sc->sc_ogain;
654 break;
655 case UDA1341_MIXER_DE:
656 if (mixer->type != AUDIO_MIXER_ENUM)
657 return EINVAL;
658
659 mixer->un.ord = sc->sc_deemphasis;
660 break;
661 case UDA1341_MIXER_INMIX1:
662 if (mixer->type != AUDIO_MIXER_VALUE)
663 return EINVAL;
664
665 mixer->un.value.level[0] = sc->sc_inmix1;
666 break;
667 case UDA1341_MIXER_INMIX2:
668 if (mixer->type != AUDIO_MIXER_VALUE)
669 return EINVAL;
670
671 mixer->un.value.level[0] = sc->sc_inmix2;
672 break;
673 case UDA1341_MIXER_MICVOL:
674 if (mixer->type != AUDIO_MIXER_VALUE)
675 return EINVAL;
676
677 mixer->un.value.level[0] = sc->sc_micvol;
678 break;
679 case UDA1341_MIXER_INMODE:
680 if (mixer->type != AUDIO_MIXER_ENUM)
681 return EINVAL;
682
683 mixer->un.ord = sc->sc_inmode;
684 break;
685 case UDA1341_MIXER_AGC:
686 if (mixer->type != AUDIO_MIXER_ENUM)
687 return EINVAL;
688
689 mixer->un.ord = sc->sc_agc;
690 break;
691 case UDA1341_MIXER_AGC_LVL:
692 if (mixer->type != AUDIO_MIXER_VALUE)
693 return EINVAL;
694
695 mixer->un.value.level[0] = sc->sc_agc_lvl;
696 break;
697 case UDA1341_MIXER_IN_GAIN2:
698 if (mixer->type != AUDIO_MIXER_VALUE)
699 return EINVAL;
700
701 mixer->un.value.level[0] = sc->sc_ch2_gain;
702 break;
703 default:
704 return EINVAL;
705 }
706
707 return 0;
708 }
709
710 int
711 uda1341_set_port(void *handle, mixer_ctrl_t *mixer)
712 {
713 struct uda1341_softc *sc = handle;
714
715 switch(mixer->dev) {
716 case UDA1341_MIXER_VOL:
717 sc->sc_volume = mixer->un.value.level[0];
718 break;
719 case UDA1341_MIXER_BASS:
720 sc->sc_bass = mixer->un.value.level[0];
721 break;
722 case UDA1341_MIXER_TREBLE:
723 sc->sc_treble = mixer->un.value.level[0];
724 break;
725 case UDA1341_MIXER_MODE:
726 sc->sc_mode = mixer->un.ord;
727 break;
728 case UDA1341_MIXER_MUTE:
729 sc->sc_mute = mixer->un.ord;
730 break;
731 case UDA1341_MIXER_OGAIN:
732 sc->sc_ogain = mixer->un.ord;
733 break;
734 case UDA1341_MIXER_DE:
735 sc->sc_deemphasis = mixer->un.ord;
736 break;
737 case UDA1341_MIXER_INMIX1:
738 sc->sc_inmix1 = mixer->un.value.level[0];
739 break;
740 case UDA1341_MIXER_INMIX2:
741 sc->sc_inmix2 = mixer->un.value.level[0];
742 break;
743 case UDA1341_MIXER_MICVOL:
744 sc->sc_micvol = mixer->un.value.level[0];
745 break;
746 case UDA1341_MIXER_INMODE:
747 sc->sc_inmode = mixer->un.ord;
748 break;
749 case UDA1341_MIXER_AGC:
750 sc->sc_agc = mixer->un.ord;
751 break;
752 case UDA1341_MIXER_AGC_LVL:
753 sc->sc_agc_lvl = mixer->un.value.level[0];
754 break;
755 case UDA1341_MIXER_IN_GAIN2:
756 sc->sc_ch2_gain = mixer->un.value.level[0];
757 break;
758 default:
759 return EINVAL;
760 }
761
762 uda1341_update_sound_settings(sc);
763
764 return 0;
765 }
766