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_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 50const 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 66static void uda1341_update_sound_settings(struct uda1341_softc *sc); 67 68 69int 70uda1341_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 94int 95uda1341_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 136int 137uda1341_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 171void 172uda1341_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 187int 188uda1341_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) 214static void 215uda1341_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 354int 355uda1341_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 606int 607uda1341_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 707int 708uda1341_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