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