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