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