Home | History | Annotate | Line # | Download | only in ic
      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/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
     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
     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
    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
    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
    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
    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
    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
    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