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