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 50static void uda1341_update_sound_settings(struct uda1341_softc *sc); 51 52 53int 54uda1341_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 78int 79uda1341_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 113void 114uda1341_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 129int 130uda1341_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) 156static void 157uda1341_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 296int 297uda1341_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 548int 549uda1341_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 649int 650uda1341_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