ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / sound / drivers / vx / vx_mixer.c
1 /*
2  * Driver for Digigram VX soundcards
3  *
4  * Common mixer part
5  *
6  * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7  *
8  *   This program is free software; you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <sound/driver.h>
24 #include <sound/core.h>
25 #include <sound/control.h>
26 #include <sound/vx_core.h>
27 #include "vx_cmd.h"
28
29 #define chip_t vx_core_t
30
31
32 /*
33  * write a codec data (24bit)
34  */
35 static void vx_write_codec_reg(vx_core_t *chip, int codec, unsigned int data)
36 {
37         unsigned long flags;
38
39         snd_assert(chip->ops->write_codec, return);
40
41         if (chip->chip_status & VX_STAT_IS_STALE)
42                 return;
43
44         spin_lock_irqsave(&chip->lock, flags);
45         chip->ops->write_codec(chip, codec, data);
46         spin_unlock_irqrestore(&chip->lock, flags);
47 }
48
49 /*
50  * Data type used to access the Codec
51  */
52 typedef union {
53         u32 l;
54 #ifdef SNDRV_BIG_ENDIAN
55         struct w {
56                 u16 h;
57                 u16 l;
58         } w;
59         struct b {
60                 u8 hh;
61                 u8 mh;
62                 u8 ml;
63                 u8 ll;
64         } b;
65 #else /* LITTLE_ENDIAN */
66         struct w {
67                 u16 l;
68                 u16 h;
69         } w;
70         struct b {
71                 u8 ll;
72                 u8 ml;
73                 u8 mh;
74                 u8 hh;
75         } b;
76 #endif
77 } vx_codec_data_t;
78
79 #define SET_CDC_DATA_SEL(di,s)          ((di).b.mh = (u8) (s))
80 #define SET_CDC_DATA_REG(di,r)          ((di).b.ml = (u8) (r))
81 #define SET_CDC_DATA_VAL(di,d)          ((di).b.ll = (u8) (d))
82 #define SET_CDC_DATA_INIT(di)           ((di).l = 0L, SET_CDC_DATA_SEL(di,XX_CODEC_SELECTOR))
83
84 /*
85  * set up codec register and write the value
86  * @codec: the codec id, 0 or 1
87  * @reg: register index
88  * @val: data value
89  */
90 static void vx_set_codec_reg(vx_core_t *chip, int codec, int reg, int val)
91 {
92         vx_codec_data_t data;
93         /* DAC control register */
94         SET_CDC_DATA_INIT(data);
95         SET_CDC_DATA_REG(data, reg);
96         SET_CDC_DATA_VAL(data, val);
97         vx_write_codec_reg(chip, codec, data.l);
98 }
99
100
101 /*
102  * vx_set_analog_output_level - set the output attenuation level
103  * @codec: the output codec, 0 or 1.  (1 for VXP440 only)
104  * @left: left output level, 0 = mute
105  * @right: right output level
106  */
107 static void vx_set_analog_output_level(vx_core_t *chip, int codec, int left, int right)
108 {
109         left  = chip->hw->output_level_max - left;
110         right = chip->hw->output_level_max - right;
111
112         if (chip->ops->akm_write) {
113                 chip->ops->akm_write(chip, XX_CODEC_LEVEL_LEFT_REGISTER, left);
114                 chip->ops->akm_write(chip, XX_CODEC_LEVEL_RIGHT_REGISTER, right);
115         } else {
116                 /* convert to attenuation level: 0 = 0dB (max), 0xe3 = -113.5 dB (min) */
117                 vx_set_codec_reg(chip, codec, XX_CODEC_LEVEL_LEFT_REGISTER, left);
118                 vx_set_codec_reg(chip, codec, XX_CODEC_LEVEL_RIGHT_REGISTER, right);
119         }
120 }
121
122
123 /*
124  * vx_toggle_dac_mute -  mute/unmute DAC
125  * @mute: 0 = unmute, 1 = mute
126  */
127
128 #define DAC_ATTEN_MIN   0x08
129 #define DAC_ATTEN_MAX   0x38
130
131 void vx_toggle_dac_mute(vx_core_t *chip, int mute)
132 {
133         unsigned int i;
134         for (i = 0; i < chip->hw->num_codecs; i++) {
135                 if (chip->ops->akm_write)
136                         chip->ops->akm_write(chip, XX_CODEC_DAC_CONTROL_REGISTER, mute); /* XXX */
137                 else
138                         vx_set_codec_reg(chip, i, XX_CODEC_DAC_CONTROL_REGISTER,
139                                          mute ? DAC_ATTEN_MAX : DAC_ATTEN_MIN);
140         }
141 }
142
143 /*
144  * vx_reset_codec - reset and initialize the codecs
145  */
146 void vx_reset_codec(vx_core_t *chip, int cold_reset)
147 {
148         unsigned int i;
149         int port = chip->type >= VX_TYPE_VXPOCKET ? 0x75 : 0x65;
150
151         chip->ops->reset_codec(chip);
152
153         /* AKM codecs should be initialized in reset_codec callback */
154         if (! chip->ops->akm_write) {
155                 /* initialize old codecs */
156                 for (i = 0; i < chip->hw->num_codecs; i++) {
157                         /* DAC control register (change level when zero crossing + mute) */
158                         vx_set_codec_reg(chip, i, XX_CODEC_DAC_CONTROL_REGISTER, DAC_ATTEN_MAX);
159                         /* ADC control register */
160                         vx_set_codec_reg(chip, i, XX_CODEC_ADC_CONTROL_REGISTER, 0x00);
161                         /* Port mode register */
162                         vx_set_codec_reg(chip, i, XX_CODEC_PORT_MODE_REGISTER, port);
163                         /* Clock control register */
164                         vx_set_codec_reg(chip, i, XX_CODEC_CLOCK_CONTROL_REGISTER, 0x00);
165                 }
166         }
167
168         /* mute analog output */
169         for (i = 0; i < chip->hw->num_codecs; i++) {
170                 chip->output_level[i][0] = 0;
171                 chip->output_level[i][1] = 0;
172                 vx_set_analog_output_level(chip, i, 0, 0);
173         }
174 }
175
176 /*
177  * change the audio input source
178  * @src: the target source (VX_AUDIO_SRC_XXX)
179  */
180 static void vx_change_audio_source(vx_core_t *chip, int src)
181 {
182         unsigned long flags;
183
184         if (chip->chip_status & VX_STAT_IS_STALE)
185                 return;
186
187         spin_lock_irqsave(&chip->lock, flags);
188         chip->ops->change_audio_source(chip, src);
189         spin_unlock_irqrestore(&chip->lock, flags);
190 }
191
192
193 /*
194  * change the audio source if necessary and possible
195  * returns 1 if the source is actually changed.
196  */
197 int vx_sync_audio_source(vx_core_t *chip)
198 {
199         if (chip->audio_source_target == chip->audio_source ||
200             chip->pcm_running)
201                 return 0;
202         vx_change_audio_source(chip, chip->audio_source_target);
203         chip->audio_source = chip->audio_source_target;
204         return 1;
205 }
206
207
208 /*
209  * audio level, mute, monitoring
210  */
211 struct vx_audio_level {
212         unsigned int has_level: 1;
213         unsigned int has_monitor_level: 1;
214         unsigned int has_mute: 1;
215         unsigned int has_monitor_mute: 1;
216         unsigned int mute;
217         unsigned int monitor_mute;
218         short level;
219         short monitor_level;
220 };
221
222 static int vx_adjust_audio_level(vx_core_t *chip, int audio, int capture,
223                                  struct vx_audio_level *info)
224 {
225         struct vx_rmh rmh;
226
227         if (chip->chip_status & VX_STAT_IS_STALE)
228                 return -EBUSY;
229
230         vx_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
231         if (capture)
232                 rmh.Cmd[0] |= COMMAND_RECORD_MASK;
233         /* Add Audio IO mask */
234         rmh.Cmd[1] = 1 << audio;
235         rmh.Cmd[2] = 0;
236         if (info->has_level) {
237                 rmh.Cmd[0] |=  VALID_AUDIO_IO_DIGITAL_LEVEL;
238                 rmh.Cmd[2] |= info->level;
239         }
240         if (info->has_monitor_level) {
241                 rmh.Cmd[0] |=  VALID_AUDIO_IO_MONITORING_LEVEL;
242                 rmh.Cmd[2] |= ((unsigned int)info->monitor_level << 10);
243         }
244         if (info->has_mute) { 
245                 rmh.Cmd[0] |= VALID_AUDIO_IO_MUTE_LEVEL;
246                 if (info->mute)
247                         rmh.Cmd[2] |= AUDIO_IO_HAS_MUTE_LEVEL;
248         }
249         if (info->has_monitor_mute) {
250                 /* validate flag for M2 at least to unmute it */ 
251                 rmh.Cmd[0] |=  VALID_AUDIO_IO_MUTE_MONITORING_1 | VALID_AUDIO_IO_MUTE_MONITORING_2;
252                 if (info->monitor_mute)
253                         rmh.Cmd[2] |= AUDIO_IO_HAS_MUTE_MONITORING_1;
254         }
255
256         return vx_send_msg(chip, &rmh);
257 }
258
259     
260 #if 0 // not used
261 static int vx_read_audio_level(vx_core_t *chip, int audio, int capture,
262                                struct vx_audio_level *info)
263 {
264         int err;
265         struct vx_rmh rmh;
266
267         memset(info, 0, sizeof(*info));
268         vx_init_rmh(&rmh, CMD_GET_AUDIO_LEVELS);
269         if (capture)
270                 rmh.Cmd[0] |= COMMAND_RECORD_MASK;
271         /* Add Audio IO mask */
272         rmh.Cmd[1] = 1 << audio;
273         err = vx_send_msg(chip, &rmh);
274         if (err < 0)
275                 return err;
276         info.level = rmh.Stat[0] & MASK_DSP_WORD_LEVEL;
277         info.monitor_level = (rmh.Stat[0] >> 10) & MASK_DSP_WORD_LEVEL;
278         info.mute = (rmh.Stat[i] & AUDIO_IO_HAS_MUTE_LEVEL) ? 1 : 0;
279         info.monitor_mute = (rmh.Stat[i] & AUDIO_IO_HAS_MUTE_MONITORING_1) ? 1 : 0;
280         return 0;
281 }
282 #endif // not used
283
284 /*
285  * set the monitoring level and mute state of the given audio
286  * no more static, because must be called from vx_pcm to demute monitoring
287  */
288 int vx_set_monitor_level(vx_core_t *chip, int audio, int level, int active)
289 {
290         struct vx_audio_level info;
291
292         memset(&info, 0, sizeof(info));
293         info.has_monitor_level = 1;
294         info.monitor_level = level;
295         info.has_monitor_mute = 1;
296         info.monitor_mute = !active;
297         chip->audio_monitor[audio] = level;
298         chip->audio_monitor_active[audio] = active;
299         return vx_adjust_audio_level(chip, audio, 0, &info); /* playback only */
300 }
301
302
303 /*
304  * set the mute status of the given audio
305  */
306 static int vx_set_audio_switch(vx_core_t *chip, int audio, int active)
307 {
308         struct vx_audio_level info;
309
310         memset(&info, 0, sizeof(info));
311         info.has_mute = 1;
312         info.mute = !active;
313         chip->audio_active[audio] = active;
314         return vx_adjust_audio_level(chip, audio, 0, &info); /* playback only */
315 }
316
317 /*
318  * set the mute status of the given audio
319  */
320 static int vx_set_audio_gain(vx_core_t *chip, int audio, int capture, int level)
321 {
322         struct vx_audio_level info;
323
324         memset(&info, 0, sizeof(info));
325         info.has_level = 1;
326         info.level = level;
327         chip->audio_gain[capture][audio] = level;
328         return vx_adjust_audio_level(chip, audio, capture, &info);
329 }
330
331 /*
332  * reset all audio levels
333  */
334 static void vx_reset_audio_levels(vx_core_t *chip)
335 {
336         unsigned int i, c;
337         struct vx_audio_level info;
338
339         memset(chip->audio_gain, 0, sizeof(chip->audio_gain));
340         memset(chip->audio_active, 0, sizeof(chip->audio_active));
341         memset(chip->audio_monitor, 0, sizeof(chip->audio_monitor));
342         memset(chip->audio_monitor_active, 0, sizeof(chip->audio_monitor_active));
343
344         for (c = 0; c < 2; c++) {
345                 for (i = 0; i < chip->hw->num_ins * 2; i++) {
346                         memset(&info, 0, sizeof(info));
347                         if (c == 0) {
348                                 info.has_monitor_level = 1;
349                                 info.has_mute = 1;
350                                 info.has_monitor_mute = 1;
351                         }
352                         info.has_level = 1;
353                         info.level = CVAL_0DB; /* default: 0dB */
354                         vx_adjust_audio_level(chip, i, c, &info);
355                         chip->audio_gain[c][i] = CVAL_0DB;
356                         chip->audio_monitor[i] = CVAL_0DB;
357                 }
358         }
359 }
360
361
362 /*
363  * VU, peak meter record
364  */
365
366 #define VU_METER_CHANNELS       2
367
368 struct vx_vu_meter {
369         int saturated;
370         int vu_level;
371         int peak_level;
372 };
373
374 /*
375  * get the VU and peak meter values
376  * @audio: the audio index
377  * @capture: 0 = playback, 1 = capture operation
378  * @info: the array of vx_vu_meter records (size = 2).
379  */
380 static int vx_get_audio_vu_meter(vx_core_t *chip, int audio, int capture, struct vx_vu_meter *info)
381 {
382         struct vx_rmh rmh;
383         int i, err;
384
385         if (chip->chip_status & VX_STAT_IS_STALE)
386                 return -EBUSY;
387
388         vx_init_rmh(&rmh, CMD_AUDIO_VU_PIC_METER);
389         rmh.LgStat += 2 * VU_METER_CHANNELS;
390         if (capture)
391                 rmh.Cmd[0] |= COMMAND_RECORD_MASK;
392     
393         /* Add Audio IO mask */
394         rmh.Cmd[1] = 0;
395         for (i = 0; i < VU_METER_CHANNELS; i++)
396                 rmh.Cmd[1] |= 1 << (audio + i);
397         err = vx_send_msg(chip, &rmh);
398         if (err < 0)
399                 return err;
400         /* Read response */
401         for (i = 0; i < 2 * VU_METER_CHANNELS; i +=2) {
402                 info->saturated = (rmh.Stat[0] & (1 << (audio + i))) ? 1 : 0;
403                 info->vu_level = rmh.Stat[i + 1];
404                 info->peak_level = rmh.Stat[i + 2];
405                 info++;
406         }
407         return 0;
408 }
409    
410
411 /*
412  * control API entries
413  */
414
415 /*
416  * output level control
417  */
418 static int vx_output_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
419 {
420         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
421         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
422         uinfo->count = 2;
423         uinfo->value.integer.min = 0;
424         uinfo->value.integer.max = chip->hw->output_level_max;
425         return 0;
426 }
427
428 static int vx_output_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
429 {
430         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
431         int codec = kcontrol->id.index;
432         down(&chip->mixer_mutex);
433         ucontrol->value.integer.value[0] = chip->output_level[codec][0];
434         ucontrol->value.integer.value[1] = chip->output_level[codec][1];
435         up(&chip->mixer_mutex);
436         return 0;
437 }
438
439 static int vx_output_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
440 {
441         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
442         int codec = kcontrol->id.index;
443         down(&chip->mixer_mutex);
444         if (ucontrol->value.integer.value[0] != chip->output_level[codec][0] ||
445             ucontrol->value.integer.value[1] != chip->output_level[codec][1]) {
446                 vx_set_analog_output_level(chip, codec,
447                                            ucontrol->value.integer.value[0],
448                                            ucontrol->value.integer.value[1]);
449                 chip->output_level[codec][0] = ucontrol->value.integer.value[0];
450                 chip->output_level[codec][1] = ucontrol->value.integer.value[1];
451                 up(&chip->mixer_mutex);
452                 return 1;
453         }
454         up(&chip->mixer_mutex);
455         return 0;
456 }
457
458 static snd_kcontrol_new_t vx_control_output_level = {
459         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
460         .name =         "Master Playback Volume",
461         .info =         vx_output_level_info,
462         .get =          vx_output_level_get,
463         .put =          vx_output_level_put,
464 };
465
466 /*
467  * audio source select
468  */
469 static int vx_audio_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
470 {
471         static char *texts_mic[3] = {
472                 "Digital", "Line", "Mic"
473         };
474         static char *texts_vx2[2] = {
475                 "Digital", "Analog"
476         };
477         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
478
479         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
480         uinfo->count = 1;
481         if (chip->type >= VX_TYPE_VXPOCKET) {
482                 uinfo->value.enumerated.items = 3;
483                 if (uinfo->value.enumerated.item > 2)
484                         uinfo->value.enumerated.item = 2;
485                 strcpy(uinfo->value.enumerated.name,
486                        texts_mic[uinfo->value.enumerated.item]);
487         } else {
488                 uinfo->value.enumerated.items = 2;
489                 if (uinfo->value.enumerated.item > 1)
490                         uinfo->value.enumerated.item = 1;
491                 strcpy(uinfo->value.enumerated.name,
492                        texts_vx2[uinfo->value.enumerated.item]);
493         }
494         return 0;
495 }
496
497 static int vx_audio_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
498 {
499         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
500         ucontrol->value.enumerated.item[0] = chip->audio_source_target;
501         return 0;
502 }
503
504 static int vx_audio_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
505 {
506         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
507         down(&chip->mixer_mutex);
508         if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) {
509                 chip->audio_source_target = ucontrol->value.enumerated.item[0];
510                 vx_sync_audio_source(chip);
511                 up(&chip->mixer_mutex);
512                 return 1;
513         }
514         up(&chip->mixer_mutex);
515         return 0;
516 }
517
518 static snd_kcontrol_new_t vx_control_audio_src = {
519         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
520         .name =         "Capture Source",
521         .info =         vx_audio_src_info,
522         .get =          vx_audio_src_get,
523         .put =          vx_audio_src_put,
524 };
525
526 /*
527  * Audio Gain
528  */
529 static int vx_audio_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
530 {
531         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
532         uinfo->count = 2;
533         uinfo->value.integer.min = 0;
534         uinfo->value.integer.max = CVAL_MAX;
535         return 0;
536 }
537
538 static int vx_audio_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
539 {
540         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
541         int audio = kcontrol->private_value & 0xff;
542         int capture = (kcontrol->private_value >> 8) & 1;
543
544         down(&chip->mixer_mutex);
545         ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio];
546         ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1];
547         up(&chip->mixer_mutex);
548         return 0;
549 }
550
551 static int vx_audio_gain_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
552 {
553         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
554         int audio = kcontrol->private_value & 0xff;
555         int capture = (kcontrol->private_value >> 8) & 1;
556
557         down(&chip->mixer_mutex);
558         if (ucontrol->value.integer.value[0] != chip->audio_gain[capture][audio] ||
559             ucontrol->value.integer.value[1] != chip->audio_gain[capture][audio+1]) {
560                 vx_set_audio_gain(chip, audio, capture, ucontrol->value.integer.value[0]);
561                 vx_set_audio_gain(chip, audio+1, capture, ucontrol->value.integer.value[1]);
562                 up(&chip->mixer_mutex);
563                 return 1;
564         }
565         up(&chip->mixer_mutex);
566         return 0;
567 }
568
569 static int vx_audio_monitor_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
570 {
571         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
572         int audio = kcontrol->private_value & 0xff;
573
574         down(&chip->mixer_mutex);
575         ucontrol->value.integer.value[0] = chip->audio_monitor[audio];
576         ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1];
577         up(&chip->mixer_mutex);
578         return 0;
579 }
580
581 static int vx_audio_monitor_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
582 {
583         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
584         int audio = kcontrol->private_value & 0xff;
585
586         down(&chip->mixer_mutex);
587         if (ucontrol->value.integer.value[0] != chip->audio_monitor[audio] ||
588             ucontrol->value.integer.value[1] != chip->audio_monitor[audio+1]) {
589                 vx_set_monitor_level(chip, audio, ucontrol->value.integer.value[0],
590                                      chip->audio_monitor_active[audio]);
591                 vx_set_monitor_level(chip, audio+1, ucontrol->value.integer.value[1],
592                                      chip->audio_monitor_active[audio+1]);
593                 up(&chip->mixer_mutex);
594                 return 1;
595         }
596         up(&chip->mixer_mutex);
597         return 0;
598 }
599
600 static int vx_audio_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
601 {
602         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
603         uinfo->count = 2;
604         uinfo->value.integer.min = 0;
605         uinfo->value.integer.max = 1;
606         return 0;
607 }
608
609 static int vx_audio_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
610 {
611         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
612         int audio = kcontrol->private_value & 0xff;
613
614         down(&chip->mixer_mutex);
615         ucontrol->value.integer.value[0] = chip->audio_active[audio];
616         ucontrol->value.integer.value[1] = chip->audio_active[audio+1];
617         up(&chip->mixer_mutex);
618         return 0;
619 }
620
621 static int vx_audio_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
622 {
623         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
624         int audio = kcontrol->private_value & 0xff;
625
626         down(&chip->mixer_mutex);
627         if (ucontrol->value.integer.value[0] != chip->audio_active[audio] ||
628             ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) {
629                 vx_set_audio_switch(chip, audio, ucontrol->value.integer.value[0]);
630                 vx_set_audio_switch(chip, audio+1, ucontrol->value.integer.value[1]);
631                 up(&chip->mixer_mutex);
632                 return 1;
633         }
634         up(&chip->mixer_mutex);
635         return 0;
636 }
637
638 static int vx_monitor_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
639 {
640         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
641         int audio = kcontrol->private_value & 0xff;
642
643         down(&chip->mixer_mutex);
644         ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio];
645         ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1];
646         up(&chip->mixer_mutex);
647         return 0;
648 }
649
650 static int vx_monitor_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
651 {
652         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
653         int audio = kcontrol->private_value & 0xff;
654
655         down(&chip->mixer_mutex);
656         if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] ||
657             ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) {
658                 vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
659                                      ucontrol->value.integer.value[0]);
660                 vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
661                                      ucontrol->value.integer.value[1]);
662                 up(&chip->mixer_mutex);
663                 return 1;
664         }
665         up(&chip->mixer_mutex);
666         return 0;
667 }
668
669 static snd_kcontrol_new_t vx_control_audio_gain = {
670         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
671         /* name will be filled later */
672         .info =         vx_audio_gain_info,
673         .get =          vx_audio_gain_get,
674         .put =          vx_audio_gain_put
675 };
676 static snd_kcontrol_new_t vx_control_output_switch = {
677         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
678         .name =         "PCM Playback Switch",
679         .info =         vx_audio_sw_info,
680         .get =          vx_audio_sw_get,
681         .put =          vx_audio_sw_put
682 };
683 static snd_kcontrol_new_t vx_control_monitor_gain = {
684         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
685         .name =         "Monitoring Volume",
686         .info =         vx_audio_gain_info,     /* shared */
687         .get =          vx_audio_monitor_get,
688         .put =          vx_audio_monitor_put
689 };
690 static snd_kcontrol_new_t vx_control_monitor_switch = {
691         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
692         .name =         "Monitoring Switch",
693         .info =         vx_audio_sw_info,       /* shared */
694         .get =          vx_monitor_sw_get,
695         .put =          vx_monitor_sw_put
696 };
697
698
699 /*
700  * IEC958 status bits
701  */
702 static int vx_iec958_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
703 {
704         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
705         uinfo->count = 1;
706         return 0;
707 }
708
709 static int vx_iec958_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
710 {
711         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
712
713         down(&chip->mixer_mutex);
714         ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff;
715         ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff;
716         ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff;
717         ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff;
718         up(&chip->mixer_mutex);
719         return 0;
720 }
721
722 static int vx_iec958_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
723 {
724         ucontrol->value.iec958.status[0] = 0xff;
725         ucontrol->value.iec958.status[1] = 0xff;
726         ucontrol->value.iec958.status[2] = 0xff;
727         ucontrol->value.iec958.status[3] = 0xff;
728         return 0;
729 }
730
731 static int vx_iec958_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
732 {
733         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
734         unsigned int val;
735
736         val = (ucontrol->value.iec958.status[0] << 0) |
737               (ucontrol->value.iec958.status[1] << 8) |
738               (ucontrol->value.iec958.status[2] << 16) |
739               (ucontrol->value.iec958.status[3] << 24);
740         down(&chip->mixer_mutex);
741         if (chip->uer_bits != val) {
742                 chip->uer_bits = val;
743                 vx_set_iec958_status(chip, val);
744                 up(&chip->mixer_mutex);
745                 return 1;
746         }
747         up(&chip->mixer_mutex);
748         return 0;
749 }
750
751 static snd_kcontrol_new_t vx_control_iec958_mask = {
752         .access =       SNDRV_CTL_ELEM_ACCESS_READ,
753         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
754         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
755         .info =         vx_iec958_info, /* shared */
756         .get =          vx_iec958_mask_get,
757 };
758
759 static snd_kcontrol_new_t vx_control_iec958 = {
760         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
761         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
762         .info =         vx_iec958_info,
763         .get =          vx_iec958_get,
764         .put =          vx_iec958_put
765 };
766
767
768 /*
769  * VU meter
770  */
771
772 #define METER_MAX       0xff
773 #define METER_SHIFT     16
774
775 static int vx_vu_meter_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
776 {
777         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
778         uinfo->count = 2;
779         uinfo->value.integer.min = 0;
780         uinfo->value.integer.max = METER_MAX;
781         return 0;
782 }
783
784 static int vx_vu_meter_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
785 {
786         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
787         struct vx_vu_meter meter[2];
788         int audio = kcontrol->private_value & 0xff;
789         int capture = (kcontrol->private_value >> 8) & 1;
790
791         vx_get_audio_vu_meter(chip, audio, capture, meter);
792         ucontrol->value.integer.value[0] = meter[0].vu_level >> METER_SHIFT;
793         ucontrol->value.integer.value[1] = meter[1].vu_level >> METER_SHIFT;
794         return 0;
795 }
796
797 static int vx_peak_meter_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
798 {
799         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
800         struct vx_vu_meter meter[2];
801         int audio = kcontrol->private_value & 0xff;
802         int capture = (kcontrol->private_value >> 8) & 1;
803
804         vx_get_audio_vu_meter(chip, audio, capture, meter);
805         ucontrol->value.integer.value[0] = meter[0].peak_level >> METER_SHIFT;
806         ucontrol->value.integer.value[1] = meter[1].peak_level >> METER_SHIFT;
807         return 0;
808 }
809
810 static int vx_saturation_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
811 {
812         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
813         uinfo->count = 2;
814         uinfo->value.integer.min = 0;
815         uinfo->value.integer.max = 1;
816         return 0;
817 }
818
819 static int vx_saturation_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
820 {
821         vx_core_t *chip = snd_kcontrol_chip(kcontrol);
822         struct vx_vu_meter meter[2];
823         int audio = kcontrol->private_value & 0xff;
824
825         vx_get_audio_vu_meter(chip, audio, 1, meter); /* capture only */
826         ucontrol->value.integer.value[0] = meter[0].saturated;
827         ucontrol->value.integer.value[1] = meter[1].saturated;
828         return 0;
829 }
830
831 static snd_kcontrol_new_t vx_control_vu_meter = {
832         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
833         .access =       SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
834         /* name will be filled later */
835         .info =         vx_vu_meter_info,
836         .get =          vx_vu_meter_get,
837 };
838
839 static snd_kcontrol_new_t vx_control_peak_meter = {
840         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
841         .access =       SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
842         /* name will be filled later */
843         .info =         vx_vu_meter_info,       /* shared */
844         .get =          vx_peak_meter_get,
845 };
846
847 static snd_kcontrol_new_t vx_control_saturation = {
848         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
849         .name =         "Input Saturation",
850         .access =       SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
851         .info =         vx_saturation_info,
852         .get =          vx_saturation_get,
853 };
854
855
856
857 /*
858  *
859  */
860
861 int snd_vx_mixer_new(vx_core_t *chip)
862 {
863         unsigned int i, c;
864         int err;
865         snd_kcontrol_new_t temp;
866         snd_card_t *card = chip->card;
867         char name[32];
868
869         strcpy(card->mixername, card->driver);
870
871         /* output level controls */
872         for (i = 0; i < chip->hw->num_outs; i++) {
873                 temp = vx_control_output_level;
874                 temp.index = i;
875                 if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
876                         return err;
877         }
878
879         /* PCM volumes, switches, monitoring */
880         for (i = 0; i < chip->hw->num_outs; i++) {
881                 int val = i * 2;
882                 temp = vx_control_audio_gain;
883                 temp.index = i;
884                 temp.name = "PCM Playback Volume";
885                 temp.private_value = val;
886                 if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
887                         return err;
888                 temp = vx_control_output_switch;
889                 temp.index = i;
890                 temp.private_value = val;
891                 if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
892                         return err;
893                 temp = vx_control_monitor_gain;
894                 temp.index = i;
895                 temp.private_value = val;
896                 if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
897                         return err;
898                 temp = vx_control_monitor_switch;
899                 temp.index = i;
900                 temp.private_value = val;
901                 if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
902                         return err;
903         }
904         for (i = 0; i < chip->hw->num_outs; i++) {
905                 temp = vx_control_audio_gain;
906                 temp.index = i;
907                 temp.name = "PCM Capture Volume";
908                 temp.private_value = (i * 2) | (1 << 8);
909                 if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
910                         return err;
911         }
912
913         /* Audio source */
914         if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_audio_src, chip))) < 0)
915                 return err;
916         /* IEC958 controls */
917         if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958_mask, chip))) < 0)
918                 return err;
919         if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958, chip))) < 0)
920                 return err;
921         /* VU, peak, saturation meters */
922         for (c = 0; c < 2; c++) {
923                 static char *dir[2] = { "Output", "Input" };
924                 for (i = 0; i < chip->hw->num_ins; i++) {
925                         int val = (i * 2) | (c << 8);
926                         if (c == 1) {
927                                 temp = vx_control_saturation;
928                                 temp.index = i;
929                                 temp.private_value = val;
930                                 if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
931                                         return err;
932                         }
933                         sprintf(name, "%s VU Meter", dir[c]);
934                         temp = vx_control_vu_meter;
935                         temp.index = i;
936                         temp.name = name;
937                         temp.private_value = val;
938                         if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
939                                 return err;
940                         sprintf(name, "%s Peak Meter", dir[c]);
941                         temp = vx_control_peak_meter;
942                         temp.index = i;
943                         temp.name = name;
944                         temp.private_value = val;
945                         if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
946                                 return err;
947                 }
948         }
949         vx_reset_audio_levels(chip);
950         return 0;
951 }