~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/pcxhr/pcxhr_mixer.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 #define __NO_VERSION__
  3 /*
  4  * Driver for Digigram pcxhr compatible soundcards
  5  *
  6  * mixer callbacks
  7  *
  8  * Copyright (c) 2004 by Digigram <alsa@digigram.com>
  9  */
 10 
 11 #include <linux/time.h>
 12 #include <linux/interrupt.h>
 13 #include <linux/init.h>
 14 #include <linux/mutex.h>
 15 #include <sound/core.h>
 16 #include "pcxhr.h"
 17 #include "pcxhr_hwdep.h"
 18 #include "pcxhr_core.h"
 19 #include <sound/control.h>
 20 #include <sound/tlv.h>
 21 #include <sound/asoundef.h>
 22 #include "pcxhr_mixer.h"
 23 #include "pcxhr_mix22.h"
 24 
 25 #define PCXHR_LINE_CAPTURE_LEVEL_MIN   0        /* -112.0 dB */
 26 #define PCXHR_LINE_CAPTURE_LEVEL_MAX   255      /* +15.5 dB */
 27 #define PCXHR_LINE_CAPTURE_ZERO_LEVEL  224      /* 0.0 dB ( 0 dBu -> 0 dBFS ) */
 28 
 29 #define PCXHR_LINE_PLAYBACK_LEVEL_MIN  0        /* -104.0 dB */
 30 #define PCXHR_LINE_PLAYBACK_LEVEL_MAX  128      /* +24.0 dB */
 31 #define PCXHR_LINE_PLAYBACK_ZERO_LEVEL 104      /* 0.0 dB ( 0 dBFS -> 0 dBu ) */
 32 
 33 static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -11200, 50, 1550);
 34 static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
 35 
 36 static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_capture, -11150, 50, 1600);
 37 static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_playback, -2550, 50, 2400);
 38 
 39 static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip,
 40                                            int is_capture, int channel)
 41 {
 42         int err, vol;
 43         struct pcxhr_rmh rmh;
 44 
 45         pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
 46         if (is_capture) {
 47                 rmh.cmd[0] |= IO_NUM_REG_IN_ANA_LEVEL;
 48                 rmh.cmd[2] = chip->analog_capture_volume[channel];
 49         } else {
 50                 rmh.cmd[0] |= IO_NUM_REG_OUT_ANA_LEVEL;
 51                 if (chip->analog_playback_active[channel])
 52                         vol = chip->analog_playback_volume[channel];
 53                 else
 54                         vol = PCXHR_LINE_PLAYBACK_LEVEL_MIN;
 55                 /* playback analog levels are inversed */
 56                 rmh.cmd[2] = PCXHR_LINE_PLAYBACK_LEVEL_MAX - vol;
 57         }
 58         rmh.cmd[1]  = 1 << ((2 * chip->chip_idx) + channel);    /* audio mask */
 59         rmh.cmd_len = 3;
 60         err = pcxhr_send_msg(chip->mgr, &rmh);
 61         if (err < 0) {
 62                 dev_dbg(chip->card->dev,
 63                         "error update_analog_audio_level card(%d)"
 64                            " is_capture(%d) err(%x)\n",
 65                            chip->chip_idx, is_capture, err);
 66                 return -EINVAL;
 67         }
 68         return 0;
 69 }
 70 
 71 /*
 72  * analog level control
 73  */
 74 static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
 75                                  struct snd_ctl_elem_info *uinfo)
 76 {
 77         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
 78 
 79         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 80         uinfo->count = 2;
 81         if (kcontrol->private_value == 0) {     /* playback */
 82             if (chip->mgr->is_hr_stereo) {
 83                 uinfo->value.integer.min =
 84                         HR222_LINE_PLAYBACK_LEVEL_MIN;  /* -25 dB */
 85                 uinfo->value.integer.max =
 86                         HR222_LINE_PLAYBACK_LEVEL_MAX;  /* +24 dB */
 87             } else {
 88                 uinfo->value.integer.min =
 89                         PCXHR_LINE_PLAYBACK_LEVEL_MIN;  /*-104 dB */
 90                 uinfo->value.integer.max =
 91                         PCXHR_LINE_PLAYBACK_LEVEL_MAX;  /* +24 dB */
 92             }
 93         } else {                                /* capture */
 94             if (chip->mgr->is_hr_stereo) {
 95                 uinfo->value.integer.min =
 96                         HR222_LINE_CAPTURE_LEVEL_MIN;   /*-112 dB */
 97                 uinfo->value.integer.max =
 98                         HR222_LINE_CAPTURE_LEVEL_MAX;   /* +15.5 dB */
 99             } else {
100                 uinfo->value.integer.min =
101                         PCXHR_LINE_CAPTURE_LEVEL_MIN;   /*-112 dB */
102                 uinfo->value.integer.max =
103                         PCXHR_LINE_CAPTURE_LEVEL_MAX;   /* +15.5 dB */
104             }
105         }
106         return 0;
107 }
108 
109 static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
110                                 struct snd_ctl_elem_value *ucontrol)
111 {
112         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
113         mutex_lock(&chip->mgr->mixer_mutex);
114         if (kcontrol->private_value == 0) {     /* playback */
115           ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
116           ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
117         } else {                                /* capture */
118           ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
119           ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
120         }
121         mutex_unlock(&chip->mgr->mixer_mutex);
122         return 0;
123 }
124 
125 static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
126                                 struct snd_ctl_elem_value *ucontrol)
127 {
128         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
129         int changed = 0;
130         int is_capture, i;
131 
132         mutex_lock(&chip->mgr->mixer_mutex);
133         is_capture = (kcontrol->private_value != 0);
134         for (i = 0; i < 2; i++) {
135                 int  new_volume = ucontrol->value.integer.value[i];
136                 int *stored_volume = is_capture ?
137                         &chip->analog_capture_volume[i] :
138                         &chip->analog_playback_volume[i];
139                 if (is_capture) {
140                         if (chip->mgr->is_hr_stereo) {
141                                 if (new_volume < HR222_LINE_CAPTURE_LEVEL_MIN ||
142                                     new_volume > HR222_LINE_CAPTURE_LEVEL_MAX)
143                                         continue;
144                         } else {
145                                 if (new_volume < PCXHR_LINE_CAPTURE_LEVEL_MIN ||
146                                     new_volume > PCXHR_LINE_CAPTURE_LEVEL_MAX)
147                                         continue;
148                         }
149                 } else {
150                         if (chip->mgr->is_hr_stereo) {
151                                 if (new_volume < HR222_LINE_PLAYBACK_LEVEL_MIN ||
152                                     new_volume > HR222_LINE_PLAYBACK_LEVEL_MAX)
153                                         continue;
154                         } else {
155                                 if (new_volume < PCXHR_LINE_PLAYBACK_LEVEL_MIN ||
156                                     new_volume > PCXHR_LINE_PLAYBACK_LEVEL_MAX)
157                                         continue;
158                         }
159                 }
160                 if (*stored_volume != new_volume) {
161                         *stored_volume = new_volume;
162                         changed = 1;
163                         if (chip->mgr->is_hr_stereo)
164                                 hr222_update_analog_audio_level(chip,
165                                                                 is_capture, i);
166                         else
167                                 pcxhr_update_analog_audio_level(chip,
168                                                                 is_capture, i);
169                 }
170         }
171         mutex_unlock(&chip->mgr->mixer_mutex);
172         return changed;
173 }
174 
175 static const struct snd_kcontrol_new pcxhr_control_analog_level = {
176         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
177         .access =       (SNDRV_CTL_ELEM_ACCESS_READWRITE |
178                          SNDRV_CTL_ELEM_ACCESS_TLV_READ),
179         /* name will be filled later */
180         .info =         pcxhr_analog_vol_info,
181         .get =          pcxhr_analog_vol_get,
182         .put =          pcxhr_analog_vol_put,
183         /* tlv will be filled later */
184 };
185 
186 /* shared */
187 
188 #define pcxhr_sw_info           snd_ctl_boolean_stereo_info
189 
190 static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
191                               struct snd_ctl_elem_value *ucontrol)
192 {
193         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
194 
195         mutex_lock(&chip->mgr->mixer_mutex);
196         ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
197         ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
198         mutex_unlock(&chip->mgr->mixer_mutex);
199         return 0;
200 }
201 
202 static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
203                               struct snd_ctl_elem_value *ucontrol)
204 {
205         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
206         int i, changed = 0;
207         mutex_lock(&chip->mgr->mixer_mutex);
208         for(i = 0; i < 2; i++) {
209                 if (chip->analog_playback_active[i] !=
210                     ucontrol->value.integer.value[i]) {
211                         chip->analog_playback_active[i] =
212                                 !!ucontrol->value.integer.value[i];
213                         changed = 1;
214                         /* update playback levels */
215                         if (chip->mgr->is_hr_stereo)
216                                 hr222_update_analog_audio_level(chip, 0, i);
217                         else
218                                 pcxhr_update_analog_audio_level(chip, 0, i);
219                 }
220         }
221         mutex_unlock(&chip->mgr->mixer_mutex);
222         return changed;
223 }
224 
225 static const struct snd_kcontrol_new pcxhr_control_output_switch = {
226         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
227         .name =         "Master Playback Switch",
228         .info =         pcxhr_sw_info,          /* shared */
229         .get =          pcxhr_audio_sw_get,
230         .put =          pcxhr_audio_sw_put
231 };
232 
233 
234 #define PCXHR_DIGITAL_LEVEL_MIN         0x000   /* -110 dB */
235 #define PCXHR_DIGITAL_LEVEL_MAX         0x1ff   /* +18 dB */
236 #define PCXHR_DIGITAL_ZERO_LEVEL        0x1b7   /*  0 dB */
237 
238 static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10975, 25, 1800);
239 
240 #define MORE_THAN_ONE_STREAM_LEVEL      0x000001
241 #define VALID_STREAM_PAN_LEVEL_MASK     0x800000
242 #define VALID_STREAM_LEVEL_MASK         0x400000
243 #define VALID_STREAM_LEVEL_1_MASK       0x200000
244 #define VALID_STREAM_LEVEL_2_MASK       0x100000
245 
246 static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
247 {
248         int err;
249         struct pcxhr_rmh rmh;
250         struct pcxhr_pipe *pipe = &chip->playback_pipe;
251         int left, right;
252 
253         if (chip->digital_playback_active[idx][0])
254                 left = chip->digital_playback_volume[idx][0];
255         else
256                 left = PCXHR_DIGITAL_LEVEL_MIN;
257         if (chip->digital_playback_active[idx][1])
258                 right = chip->digital_playback_volume[idx][1];
259         else
260                 right = PCXHR_DIGITAL_LEVEL_MIN;
261 
262         pcxhr_init_rmh(&rmh, CMD_STREAM_OUT_LEVEL_ADJUST);
263         /* add pipe and stream mask */
264         pcxhr_set_pipe_cmd_params(&rmh, 0, pipe->first_audio, 0, 1<<idx);
265         /* volume left->left / right->right panoramic level */
266         rmh.cmd[0] |= MORE_THAN_ONE_STREAM_LEVEL;
267         rmh.cmd[2]  = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_1_MASK;
268         rmh.cmd[2] |= (left << 10);
269         rmh.cmd[3]  = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_2_MASK;
270         rmh.cmd[3] |= right;
271         rmh.cmd_len = 4;
272 
273         err = pcxhr_send_msg(chip->mgr, &rmh);
274         if (err < 0) {
275                 dev_dbg(chip->card->dev, "error update_playback_stream_level "
276                            "card(%d) err(%x)\n", chip->chip_idx, err);
277                 return -EINVAL;
278         }
279         return 0;
280 }
281 
282 #define AUDIO_IO_HAS_MUTE_LEVEL         0x400000
283 #define AUDIO_IO_HAS_MUTE_MONITOR_1     0x200000
284 #define VALID_AUDIO_IO_DIGITAL_LEVEL    0x000001
285 #define VALID_AUDIO_IO_MONITOR_LEVEL    0x000002
286 #define VALID_AUDIO_IO_MUTE_LEVEL       0x000004
287 #define VALID_AUDIO_IO_MUTE_MONITOR_1   0x000008
288 
289 static int pcxhr_update_audio_pipe_level(struct snd_pcxhr *chip,
290                                          int capture, int channel)
291 {
292         int err;
293         struct pcxhr_rmh rmh;
294         struct pcxhr_pipe *pipe;
295 
296         if (capture)
297                 pipe = &chip->capture_pipe[0];
298         else
299                 pipe = &chip->playback_pipe;
300 
301         pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
302         /* add channel mask */
303         pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0,
304                                   1 << (channel + pipe->first_audio));
305         /* TODO : if mask (3 << pipe->first_audio) is used, left and right
306          * channel will be programmed to the same params */
307         if (capture) {
308                 rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
309                 /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled
310                  * (capture pipe level) */
311                 rmh.cmd[2] = chip->digital_capture_volume[channel];
312         } else {
313                 rmh.cmd[0] |=   VALID_AUDIO_IO_MONITOR_LEVEL |
314                                 VALID_AUDIO_IO_MUTE_MONITOR_1;
315                 /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL
316                  * not yet handled (playback pipe level)
317                  */
318                 rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
319                 if (chip->monitoring_active[channel] == 0)
320                         rmh.cmd[2] |= AUDIO_IO_HAS_MUTE_MONITOR_1;
321         }
322         rmh.cmd_len = 3;
323 
324         err = pcxhr_send_msg(chip->mgr, &rmh);
325         if (err < 0) {
326                 dev_dbg(chip->card->dev,
327                         "error update_audio_level(%d) err=%x\n",
328                            chip->chip_idx, err);
329                 return -EINVAL;
330         }
331         return 0;
332 }
333 
334 
335 /* shared */
336 static int pcxhr_digital_vol_info(struct snd_kcontrol *kcontrol,
337                                   struct snd_ctl_elem_info *uinfo)
338 {
339         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
340         uinfo->count = 2;
341         uinfo->value.integer.min = PCXHR_DIGITAL_LEVEL_MIN;   /* -109.5 dB */
342         uinfo->value.integer.max = PCXHR_DIGITAL_LEVEL_MAX;   /*   18.0 dB */
343         return 0;
344 }
345 
346 
347 static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
348                              struct snd_ctl_elem_value *ucontrol)
349 {
350         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
351         int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
352         int *stored_volume;
353         int is_capture = kcontrol->private_value;
354 
355         mutex_lock(&chip->mgr->mixer_mutex);
356         if (is_capture)         /* digital capture */
357                 stored_volume = chip->digital_capture_volume;
358         else                    /* digital playback */
359                 stored_volume = chip->digital_playback_volume[idx];
360         ucontrol->value.integer.value[0] = stored_volume[0];
361         ucontrol->value.integer.value[1] = stored_volume[1];
362         mutex_unlock(&chip->mgr->mixer_mutex);
363         return 0;
364 }
365 
366 static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
367                              struct snd_ctl_elem_value *ucontrol)
368 {
369         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
370         int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
371         int changed = 0;
372         int is_capture = kcontrol->private_value;
373         int *stored_volume;
374         int i;
375 
376         mutex_lock(&chip->mgr->mixer_mutex);
377         if (is_capture)         /* digital capture */
378                 stored_volume = chip->digital_capture_volume;
379         else                    /* digital playback */
380                 stored_volume = chip->digital_playback_volume[idx];
381         for (i = 0; i < 2; i++) {
382                 int vol = ucontrol->value.integer.value[i];
383                 if (vol < PCXHR_DIGITAL_LEVEL_MIN ||
384                     vol > PCXHR_DIGITAL_LEVEL_MAX)
385                         continue;
386                 if (stored_volume[i] != vol) {
387                         stored_volume[i] = vol;
388                         changed = 1;
389                         if (is_capture) /* update capture volume */
390                                 pcxhr_update_audio_pipe_level(chip, 1, i);
391                 }
392         }
393         if (!is_capture && changed)     /* update playback volume */
394                 pcxhr_update_playback_stream_level(chip, idx);
395         mutex_unlock(&chip->mgr->mixer_mutex);
396         return changed;
397 }
398 
399 static const struct snd_kcontrol_new snd_pcxhr_pcm_vol =
400 {
401         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
402         .access =       (SNDRV_CTL_ELEM_ACCESS_READWRITE |
403                          SNDRV_CTL_ELEM_ACCESS_TLV_READ),
404         /* name will be filled later */
405         /* count will be filled later */
406         .info =         pcxhr_digital_vol_info,         /* shared */
407         .get =          pcxhr_pcm_vol_get,
408         .put =          pcxhr_pcm_vol_put,
409         .tlv = { .p = db_scale_digital },
410 };
411 
412 
413 static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
414                             struct snd_ctl_elem_value *ucontrol)
415 {
416         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
417         int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
418 
419         mutex_lock(&chip->mgr->mixer_mutex);
420         ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
421         ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
422         mutex_unlock(&chip->mgr->mixer_mutex);
423         return 0;
424 }
425 
426 static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
427                             struct snd_ctl_elem_value *ucontrol)
428 {
429         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
430         int changed = 0;
431         int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
432         int i, j;
433 
434         mutex_lock(&chip->mgr->mixer_mutex);
435         j = idx;
436         for (i = 0; i < 2; i++) {
437                 if (chip->digital_playback_active[j][i] !=
438                     ucontrol->value.integer.value[i]) {
439                         chip->digital_playback_active[j][i] =
440                                 !!ucontrol->value.integer.value[i];
441                         changed = 1;
442                 }
443         }
444         if (changed)
445                 pcxhr_update_playback_stream_level(chip, idx);
446         mutex_unlock(&chip->mgr->mixer_mutex);
447         return changed;
448 }
449 
450 static const struct snd_kcontrol_new pcxhr_control_pcm_switch = {
451         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
452         .name =         "PCM Playback Switch",
453         .count =        PCXHR_PLAYBACK_STREAMS,
454         .info =         pcxhr_sw_info,          /* shared */
455         .get =          pcxhr_pcm_sw_get,
456         .put =          pcxhr_pcm_sw_put
457 };
458 
459 
460 /*
461  * monitoring level control
462  */
463 
464 static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol,
465                                  struct snd_ctl_elem_value *ucontrol)
466 {
467         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
468         mutex_lock(&chip->mgr->mixer_mutex);
469         ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
470         ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
471         mutex_unlock(&chip->mgr->mixer_mutex);
472         return 0;
473 }
474 
475 static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
476                                  struct snd_ctl_elem_value *ucontrol)
477 {
478         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
479         int changed = 0;
480         int i;
481 
482         mutex_lock(&chip->mgr->mixer_mutex);
483         for (i = 0; i < 2; i++) {
484                 if (chip->monitoring_volume[i] !=
485                     ucontrol->value.integer.value[i]) {
486                         chip->monitoring_volume[i] =
487                                 ucontrol->value.integer.value[i];
488                         if (chip->monitoring_active[i])
489                                 /* update monitoring volume and mute */
490                                 /* do only when monitoring is unmuted */
491                                 pcxhr_update_audio_pipe_level(chip, 0, i);
492                         changed = 1;
493                 }
494         }
495         mutex_unlock(&chip->mgr->mixer_mutex);
496         return changed;
497 }
498 
499 static const struct snd_kcontrol_new pcxhr_control_monitor_vol = {
500         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
501         .access =       (SNDRV_CTL_ELEM_ACCESS_READWRITE |
502                          SNDRV_CTL_ELEM_ACCESS_TLV_READ),
503         .name =         "Monitoring Playback Volume",
504         .info =         pcxhr_digital_vol_info,         /* shared */
505         .get =          pcxhr_monitor_vol_get,
506         .put =          pcxhr_monitor_vol_put,
507         .tlv = { .p = db_scale_digital },
508 };
509 
510 /*
511  * monitoring switch control
512  */
513 
514 static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol,
515                                 struct snd_ctl_elem_value *ucontrol)
516 {
517         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
518         mutex_lock(&chip->mgr->mixer_mutex);
519         ucontrol->value.integer.value[0] = chip->monitoring_active[0];
520         ucontrol->value.integer.value[1] = chip->monitoring_active[1];
521         mutex_unlock(&chip->mgr->mixer_mutex);
522         return 0;
523 }
524 
525 static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
526                                 struct snd_ctl_elem_value *ucontrol)
527 {
528         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
529         int changed = 0;
530         int i;
531 
532         mutex_lock(&chip->mgr->mixer_mutex);
533         for (i = 0; i < 2; i++) {
534                 if (chip->monitoring_active[i] !=
535                     ucontrol->value.integer.value[i]) {
536                         chip->monitoring_active[i] =
537                                 !!ucontrol->value.integer.value[i];
538                         changed |= (1<<i); /* mask 0x01 and 0x02 */
539                 }
540         }
541         if (changed & 0x01)
542                 /* update left monitoring volume and mute */
543                 pcxhr_update_audio_pipe_level(chip, 0, 0);
544         if (changed & 0x02)
545                 /* update right monitoring volume and mute */
546                 pcxhr_update_audio_pipe_level(chip, 0, 1);
547 
548         mutex_unlock(&chip->mgr->mixer_mutex);
549         return (changed != 0);
550 }
551 
552 static const struct snd_kcontrol_new pcxhr_control_monitor_sw = {
553         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
554         .name =         "Monitoring Playback Switch",
555         .info =         pcxhr_sw_info,          /* shared */
556         .get =          pcxhr_monitor_sw_get,
557         .put =          pcxhr_monitor_sw_put
558 };
559 
560 
561 
562 /*
563  * audio source select
564  */
565 #define PCXHR_SOURCE_AUDIO01_UER        0x000100
566 #define PCXHR_SOURCE_AUDIO01_SYNC       0x000200
567 #define PCXHR_SOURCE_AUDIO23_UER        0x000400
568 #define PCXHR_SOURCE_AUDIO45_UER        0x001000
569 #define PCXHR_SOURCE_AUDIO67_UER        0x040000
570 
571 static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
572 {
573         struct pcxhr_rmh rmh;
574         unsigned int mask, reg;
575         unsigned int codec;
576         int err, changed;
577 
578         switch (chip->chip_idx) {
579         case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
580         case 1 : mask = PCXHR_SOURCE_AUDIO23_UER; codec = CS8420_23_CS; break;
581         case 2 : mask = PCXHR_SOURCE_AUDIO45_UER; codec = CS8420_45_CS; break;
582         case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
583         default: return -EINVAL;
584         }
585         if (chip->audio_capture_source != 0) {
586                 reg = mask;     /* audio source from digital plug */
587         } else {
588                 reg = 0;        /* audio source from analog plug */
589         }
590         /* set the input source */
591         pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
592         /* resync them (otherwise channel inversion possible) */
593         if (changed) {
594                 pcxhr_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
595                 rmh.cmd[0] |= (1 << chip->chip_idx);
596                 err = pcxhr_send_msg(chip->mgr, &rmh);
597                 if (err)
598                         return err;
599         }
600         if (chip->mgr->board_aes_in_192k) {
601                 int i;
602                 unsigned int src_config = 0xC0;
603                 /* update all src configs with one call */
604                 for (i = 0; (i < 4) && (i < chip->mgr->capture_chips); i++) {
605                         if (chip->mgr->chip[i]->audio_capture_source == 2)
606                                 src_config |= (1 << (3 - i));
607                 }
608                 /* set codec SRC on off */
609                 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
610                 rmh.cmd_len = 2;
611                 rmh.cmd[0] |= IO_NUM_REG_CONFIG_SRC;
612                 rmh.cmd[1] = src_config;
613                 err = pcxhr_send_msg(chip->mgr, &rmh);
614         } else {
615                 int use_src = 0;
616                 if (chip->audio_capture_source == 2)
617                         use_src = 1;
618                 /* set codec SRC on off */
619                 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
620                 rmh.cmd_len = 3;
621                 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
622                 rmh.cmd[1] = codec;
623                 rmh.cmd[2] = ((CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) |
624                               (use_src ? 0x41 : 0x54));
625                 err = pcxhr_send_msg(chip->mgr, &rmh);
626                 if (err)
627                         return err;
628                 rmh.cmd[2] = ((CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) |
629                               (use_src ? 0x41 : 0x49));
630                 err = pcxhr_send_msg(chip->mgr, &rmh);
631         }
632         return err;
633 }
634 
635 static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
636                                 struct snd_ctl_elem_info *uinfo)
637 {
638         static const char *texts[5] = {
639                 "Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"
640         };
641         int i;
642         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
643 
644         i = 2;                  /* no SRC, no Mic available */
645         if (chip->mgr->board_has_aes1) {
646                 i = 3;          /* SRC available */
647                 if (chip->mgr->board_has_mic)
648                         i = 5;  /* Mic and MicroMix available */
649         }
650         return snd_ctl_enum_info(uinfo, 1, i, texts);
651 }
652 
653 static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol,
654                                struct snd_ctl_elem_value *ucontrol)
655 {
656         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
657         ucontrol->value.enumerated.item[0] = chip->audio_capture_source;
658         return 0;
659 }
660 
661 static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
662                                struct snd_ctl_elem_value *ucontrol)
663 {
664         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
665         int ret = 0;
666         int i = 2;              /* no SRC, no Mic available */
667         if (chip->mgr->board_has_aes1) {
668                 i = 3;          /* SRC available */
669                 if (chip->mgr->board_has_mic)
670                         i = 5;  /* Mic and MicroMix available */
671         }
672         if (ucontrol->value.enumerated.item[0] >= i)
673                 return -EINVAL;
674         mutex_lock(&chip->mgr->mixer_mutex);
675         if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
676                 chip->audio_capture_source = ucontrol->value.enumerated.item[0];
677                 if (chip->mgr->is_hr_stereo)
678                         hr222_set_audio_source(chip);
679                 else
680                         pcxhr_set_audio_source(chip);
681                 ret = 1;
682         }
683         mutex_unlock(&chip->mgr->mixer_mutex);
684         return ret;
685 }
686 
687 static const struct snd_kcontrol_new pcxhr_control_audio_src = {
688         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
689         .name =         "Capture Source",
690         .info =         pcxhr_audio_src_info,
691         .get =          pcxhr_audio_src_get,
692         .put =          pcxhr_audio_src_put,
693 };
694 
695 
696 /*
697  * clock type selection
698  * enum pcxhr_clock_type {
699  *      PCXHR_CLOCK_TYPE_INTERNAL = 0,
700  *      PCXHR_CLOCK_TYPE_WORD_CLOCK,
701  *      PCXHR_CLOCK_TYPE_AES_SYNC,
702  *      PCXHR_CLOCK_TYPE_AES_1,
703  *      PCXHR_CLOCK_TYPE_AES_2,
704  *      PCXHR_CLOCK_TYPE_AES_3,
705  *      PCXHR_CLOCK_TYPE_AES_4,
706  *      PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
707  *      HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
708  *      HR22_CLOCK_TYPE_AES_SYNC,
709  *      HR22_CLOCK_TYPE_AES_1,
710  *      HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
711  * };
712  */
713 
714 static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
715                                  struct snd_ctl_elem_info *uinfo)
716 {
717         static const char *textsPCXHR[7] = {
718                 "Internal", "WordClock", "AES Sync",
719                 "AES 1", "AES 2", "AES 3", "AES 4"
720         };
721         static const char *textsHR22[3] = {
722                 "Internal", "AES Sync", "AES 1"
723         };
724         const char **texts;
725         struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
726         int clock_items = 2;    /* at least Internal and AES Sync clock */
727         if (mgr->board_has_aes1) {
728                 clock_items += mgr->capture_chips;      /* add AES x */
729                 if (!mgr->is_hr_stereo)
730                         clock_items += 1;               /* add word clock */
731         }
732         if (mgr->is_hr_stereo) {
733                 texts = textsHR22;
734                 snd_BUG_ON(clock_items > (HR22_CLOCK_TYPE_MAX+1));
735         } else {
736                 texts = textsPCXHR;
737                 snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1));
738         }
739         return snd_ctl_enum_info(uinfo, 1, clock_items, texts);
740 }
741 
742 static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol,
743                                 struct snd_ctl_elem_value *ucontrol)
744 {
745         struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
746         ucontrol->value.enumerated.item[0] = mgr->use_clock_type;
747         return 0;
748 }
749 
750 static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
751                                 struct snd_ctl_elem_value *ucontrol)
752 {
753         struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
754         int rate, ret = 0;
755         unsigned int clock_items = 2; /* at least Internal and AES Sync clock */
756         if (mgr->board_has_aes1) {
757                 clock_items += mgr->capture_chips;      /* add AES x */
758                 if (!mgr->is_hr_stereo)
759                         clock_items += 1;               /* add word clock */
760         }
761         if (ucontrol->value.enumerated.item[0] >= clock_items)
762                 return -EINVAL;
763         mutex_lock(&mgr->mixer_mutex);
764         if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) {
765                 mutex_lock(&mgr->setup_mutex);
766                 mgr->use_clock_type = ucontrol->value.enumerated.item[0];
767                 rate = 0;
768                 if (mgr->use_clock_type != PCXHR_CLOCK_TYPE_INTERNAL) {
769                         pcxhr_get_external_clock(mgr, mgr->use_clock_type,
770                                                  &rate);
771                 } else {
772                         rate = mgr->sample_rate;
773                         if (!rate)
774                                 rate = 48000;
775                 }
776                 if (rate) {
777                         pcxhr_set_clock(mgr, rate);
778                         if (mgr->sample_rate)
779                                 mgr->sample_rate = rate;
780                 }
781                 mutex_unlock(&mgr->setup_mutex);
782                 ret = 1; /* return 1 even if the set was not done. ok ? */
783         }
784         mutex_unlock(&mgr->mixer_mutex);
785         return ret;
786 }
787 
788 static const struct snd_kcontrol_new pcxhr_control_clock_type = {
789         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
790         .name =         "Clock Mode",
791         .info =         pcxhr_clock_type_info,
792         .get =          pcxhr_clock_type_get,
793         .put =          pcxhr_clock_type_put,
794 };
795 
796 /*
797  * clock rate control
798  * specific control that scans the sample rates on the external plugs
799  */
800 static int pcxhr_clock_rate_info(struct snd_kcontrol *kcontrol,
801                                  struct snd_ctl_elem_info *uinfo)
802 {
803         struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
804         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
805         uinfo->count = 3 + mgr->capture_chips;
806         uinfo->value.integer.min = 0;           /* clock not present */
807         uinfo->value.integer.max = 192000;      /* max sample rate 192 kHz */
808         return 0;
809 }
810 
811 static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
812                                 struct snd_ctl_elem_value *ucontrol)
813 {
814         struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
815         int i, err, rate;
816 
817         mutex_lock(&mgr->mixer_mutex);
818         for(i = 0; i < 3 + mgr->capture_chips; i++) {
819                 if (i == PCXHR_CLOCK_TYPE_INTERNAL)
820                         rate = mgr->sample_rate_real;
821                 else {
822                         err = pcxhr_get_external_clock(mgr, i, &rate);
823                         if (err)
824                                 break;
825                 }
826                 ucontrol->value.integer.value[i] = rate;
827         }
828         mutex_unlock(&mgr->mixer_mutex);
829         return 0;
830 }
831 
832 static const struct snd_kcontrol_new pcxhr_control_clock_rate = {
833         .access =       SNDRV_CTL_ELEM_ACCESS_READ,
834         .iface =        SNDRV_CTL_ELEM_IFACE_CARD,
835         .name =         "Clock Rates",
836         .info =         pcxhr_clock_rate_info,
837         .get =          pcxhr_clock_rate_get,
838 };
839 
840 /*
841  * IEC958 status bits
842  */
843 static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol,
844                              struct snd_ctl_elem_info *uinfo)
845 {
846         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
847         uinfo->count = 1;
848         return 0;
849 }
850 
851 static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip,
852                                      int aes_idx, unsigned char *aes_bits)
853 {
854         int i, err;
855         unsigned char temp;
856         struct pcxhr_rmh rmh;
857 
858         pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
859         rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
860         switch (chip->chip_idx) {
861           /* instead of CS8420_01_CS use CS8416_01_CS for AES SYNC plug */
862         case 0: rmh.cmd[1] = CS8420_01_CS; break;
863         case 1: rmh.cmd[1] = CS8420_23_CS; break;
864         case 2: rmh.cmd[1] = CS8420_45_CS; break;
865         case 3: rmh.cmd[1] = CS8420_67_CS; break;
866         default: return -EINVAL;
867         }
868         if (chip->mgr->board_aes_in_192k) {
869                 switch (aes_idx) {
870                 case 0: rmh.cmd[2] = CS8416_CSB0; break;
871                 case 1: rmh.cmd[2] = CS8416_CSB1; break;
872                 case 2: rmh.cmd[2] = CS8416_CSB2; break;
873                 case 3: rmh.cmd[2] = CS8416_CSB3; break;
874                 case 4: rmh.cmd[2] = CS8416_CSB4; break;
875                 default: return -EINVAL;
876                 }
877         } else {
878                 switch (aes_idx) {
879                   /* instead of CS8420_CSB0 use CS8416_CSBx for AES SYNC plug */
880                 case 0: rmh.cmd[2] = CS8420_CSB0; break;
881                 case 1: rmh.cmd[2] = CS8420_CSB1; break;
882                 case 2: rmh.cmd[2] = CS8420_CSB2; break;
883                 case 3: rmh.cmd[2] = CS8420_CSB3; break;
884                 case 4: rmh.cmd[2] = CS8420_CSB4; break;
885                 default: return -EINVAL;
886                 }
887         }
888         /* size and code the chip id for the fpga */
889         rmh.cmd[1] &= 0x0fffff;
890         /* chip signature + map for spi read */
891         rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI;
892         rmh.cmd_len = 3;
893         err = pcxhr_send_msg(chip->mgr, &rmh);
894         if (err)
895                 return err;
896 
897         if (chip->mgr->board_aes_in_192k) {
898                 temp = (unsigned char)rmh.stat[1];
899         } else {
900                 temp = 0;
901                 /* reversed bit order (not with CS8416_01_CS) */
902                 for (i = 0; i < 8; i++) {
903                         temp <<= 1;
904                         if (rmh.stat[1] & (1 << i))
905                                 temp |= 1;
906                 }
907         }
908         dev_dbg(chip->card->dev, "read iec958 AES %d byte %d = 0x%x\n",
909                     chip->chip_idx, aes_idx, temp);
910         *aes_bits = temp;
911         return 0;
912 }
913 
914 static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol,
915                             struct snd_ctl_elem_value *ucontrol)
916 {
917         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
918         unsigned char aes_bits;
919         int i, err;
920 
921         mutex_lock(&chip->mgr->mixer_mutex);
922         for(i = 0; i < 5; i++) {
923                 if (kcontrol->private_value == 0)       /* playback */
924                         aes_bits = chip->aes_bits[i];
925                 else {                          /* capture */
926                         if (chip->mgr->is_hr_stereo)
927                                 err = hr222_iec958_capture_byte(chip, i,
928                                                                 &aes_bits);
929                         else
930                                 err = pcxhr_iec958_capture_byte(chip, i,
931                                                                 &aes_bits);
932                         if (err)
933                                 break;
934                 }
935                 ucontrol->value.iec958.status[i] = aes_bits;
936         }
937         mutex_unlock(&chip->mgr->mixer_mutex);
938         return 0;
939 }
940 
941 static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
942                                  struct snd_ctl_elem_value *ucontrol)
943 {
944         int i;
945         for (i = 0; i < 5; i++)
946                 ucontrol->value.iec958.status[i] = 0xff;
947         return 0;
948 }
949 
950 static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip,
951                                     int aes_idx, unsigned char aes_bits)
952 {
953         int i, err, cmd;
954         unsigned char new_bits = aes_bits;
955         unsigned char old_bits = chip->aes_bits[aes_idx];
956         struct pcxhr_rmh rmh;
957 
958         for (i = 0; i < 8; i++) {
959                 if ((old_bits & 0x01) != (new_bits & 0x01)) {
960                         cmd = chip->chip_idx & 0x03;      /* chip index 0..3 */
961                         if (chip->chip_idx > 3)
962                                 /* new bit used if chip_idx>3 (PCX1222HR) */
963                                 cmd |= 1 << 22;
964                         cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */
965                         cmd |= (new_bits & 0x01) << 23;   /* add bit value */
966                         pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
967                         rmh.cmd[0] |= IO_NUM_REG_CUER;
968                         rmh.cmd[1] = cmd;
969                         rmh.cmd_len = 2;
970                         dev_dbg(chip->card->dev,
971                                 "write iec958 AES %d byte %d bit %d (cmd %x)\n",
972                                     chip->chip_idx, aes_idx, i, cmd);
973                         err = pcxhr_send_msg(chip->mgr, &rmh);
974                         if (err)
975                                 return err;
976                 }
977                 old_bits >>= 1;
978                 new_bits >>= 1;
979         }
980         chip->aes_bits[aes_idx] = aes_bits;
981         return 0;
982 }
983 
984 static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
985                             struct snd_ctl_elem_value *ucontrol)
986 {
987         struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
988         int i, changed = 0;
989 
990         /* playback */
991         mutex_lock(&chip->mgr->mixer_mutex);
992         for (i = 0; i < 5; i++) {
993                 if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
994                         if (chip->mgr->is_hr_stereo)
995                                 hr222_iec958_update_byte(chip, i,
996                                         ucontrol->value.iec958.status[i]);
997                         else
998                                 pcxhr_iec958_update_byte(chip, i,
999                                         ucontrol->value.iec958.status[i]);
1000                         changed = 1;
1001                 }
1002         }
1003         mutex_unlock(&chip->mgr->mixer_mutex);
1004         return changed;
1005 }
1006 
1007 static const struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = {
1008         .access =       SNDRV_CTL_ELEM_ACCESS_READ,
1009         .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
1010         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
1011         .info =         pcxhr_iec958_info,
1012         .get =          pcxhr_iec958_mask_get
1013 };
1014 static const struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
1015         .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
1016         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1017         .info =         pcxhr_iec958_info,
1018         .get =          pcxhr_iec958_get,
1019         .put =          pcxhr_iec958_put,
1020         .private_value = 0 /* playback */
1021 };
1022 
1023 static const struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = {
1024         .access =       SNDRV_CTL_ELEM_ACCESS_READ,
1025         .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
1026         .name =         SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1027         .info =         pcxhr_iec958_info,
1028         .get =          pcxhr_iec958_mask_get
1029 };
1030 static const struct snd_kcontrol_new pcxhr_control_capture_iec958 = {
1031         .access =       SNDRV_CTL_ELEM_ACCESS_READ,
1032         .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
1033         .name =         SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
1034         .info =         pcxhr_iec958_info,
1035         .get =          pcxhr_iec958_get,
1036         .private_value = 1 /* capture */
1037 };
1038 
1039 static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
1040 {
1041         int i;
1042 
1043         for (i = 0; i < 2; i++) {
1044                 if (chip->nb_streams_play) {
1045                         int j;
1046                         /* at boot time the digital volumes are unmuted 0dB */
1047                         for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {
1048                                 chip->digital_playback_active[j][i] = 1;
1049                                 chip->digital_playback_volume[j][i] =
1050                                         PCXHR_DIGITAL_ZERO_LEVEL;
1051                         }
1052                         /* after boot, only two bits are set on the uer
1053                          * interface
1054                          */
1055                         chip->aes_bits[0] = (IEC958_AES0_PROFESSIONAL |
1056                                              IEC958_AES0_PRO_FS_48000);
1057 #ifdef CONFIG_SND_DEBUG
1058                         /* analog volumes for playback
1059                          * (is LEVEL_MIN after boot)
1060                          */
1061                         chip->analog_playback_active[i] = 1;
1062                         if (chip->mgr->is_hr_stereo)
1063                                 chip->analog_playback_volume[i] =
1064                                         HR222_LINE_PLAYBACK_ZERO_LEVEL;
1065                         else {
1066                                 chip->analog_playback_volume[i] =
1067                                         PCXHR_LINE_PLAYBACK_ZERO_LEVEL;
1068                                 pcxhr_update_analog_audio_level(chip, 0, i);
1069                         }
1070 #endif
1071                         /* stereo cards need to be initialised after boot */
1072                         if (chip->mgr->is_hr_stereo)
1073                                 hr222_update_analog_audio_level(chip, 0, i);
1074                 }
1075                 if (chip->nb_streams_capt) {
1076                         /* at boot time the digital volumes are unmuted 0dB */
1077                         chip->digital_capture_volume[i] =
1078                                 PCXHR_DIGITAL_ZERO_LEVEL;
1079                         chip->analog_capture_active = 1;
1080 #ifdef CONFIG_SND_DEBUG
1081                         /* analog volumes for playback
1082                          * (is LEVEL_MIN after boot)
1083                          */
1084                         if (chip->mgr->is_hr_stereo)
1085                                 chip->analog_capture_volume[i] =
1086                                         HR222_LINE_CAPTURE_ZERO_LEVEL;
1087                         else {
1088                                 chip->analog_capture_volume[i] =
1089                                         PCXHR_LINE_CAPTURE_ZERO_LEVEL;
1090                                 pcxhr_update_analog_audio_level(chip, 1, i);
1091                         }
1092 #endif
1093                         /* stereo cards need to be initialised after boot */
1094                         if (chip->mgr->is_hr_stereo)
1095                                 hr222_update_analog_audio_level(chip, 1, i);
1096                 }
1097         }
1098 
1099         return;
1100 }
1101 
1102 
1103 int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
1104 {
1105         struct snd_pcxhr *chip;
1106         int err, i;
1107 
1108         mutex_init(&mgr->mixer_mutex); /* can be in another place */
1109 
1110         for (i = 0; i < mgr->num_cards; i++) {
1111                 struct snd_kcontrol_new temp;
1112                 chip = mgr->chip[i];
1113 
1114                 if (chip->nb_streams_play) {
1115                         /* analog output level control */
1116                         temp = pcxhr_control_analog_level;
1117                         temp.name = "Master Playback Volume";
1118                         temp.private_value = 0; /* playback */
1119                         if (mgr->is_hr_stereo)
1120                                 temp.tlv.p = db_scale_a_hr222_playback;
1121                         else
1122                                 temp.tlv.p = db_scale_analog_playback;
1123                         err = snd_ctl_add(chip->card,
1124                                           snd_ctl_new1(&temp, chip));
1125                         if (err < 0)
1126                                 return err;
1127 
1128                         /* output mute controls */
1129                         err = snd_ctl_add(chip->card,
1130                                 snd_ctl_new1(&pcxhr_control_output_switch,
1131                                              chip));
1132                         if (err < 0)
1133                                 return err;
1134 
1135                         temp = snd_pcxhr_pcm_vol;
1136                         temp.name = "PCM Playback Volume";
1137                         temp.count = PCXHR_PLAYBACK_STREAMS;
1138                         temp.private_value = 0; /* playback */
1139                         err = snd_ctl_add(chip->card,
1140                                           snd_ctl_new1(&temp, chip));
1141                         if (err < 0)
1142                                 return err;
1143 
1144                         err = snd_ctl_add(chip->card,
1145                                 snd_ctl_new1(&pcxhr_control_pcm_switch, chip));
1146                         if (err < 0)
1147                                 return err;
1148 
1149                         /* IEC958 controls */
1150                         err = snd_ctl_add(chip->card,
1151                                 snd_ctl_new1(&pcxhr_control_playback_iec958_mask,
1152                                              chip));
1153                         if (err < 0)
1154                                 return err;
1155 
1156                         err = snd_ctl_add(chip->card,
1157                                 snd_ctl_new1(&pcxhr_control_playback_iec958,
1158                                              chip));
1159                         if (err < 0)
1160                                 return err;
1161                 }
1162                 if (chip->nb_streams_capt) {
1163                         /* analog input level control */
1164                         temp = pcxhr_control_analog_level;
1165                         temp.name = "Line Capture Volume";
1166                         temp.private_value = 1; /* capture */
1167                         if (mgr->is_hr_stereo)
1168                                 temp.tlv.p = db_scale_a_hr222_capture;
1169                         else
1170                                 temp.tlv.p = db_scale_analog_capture;
1171 
1172                         err = snd_ctl_add(chip->card,
1173                                           snd_ctl_new1(&temp, chip));
1174                         if (err < 0)
1175                                 return err;
1176 
1177                         temp = snd_pcxhr_pcm_vol;
1178                         temp.name = "PCM Capture Volume";
1179                         temp.count = 1;
1180                         temp.private_value = 1; /* capture */
1181 
1182                         err = snd_ctl_add(chip->card,
1183                                           snd_ctl_new1(&temp, chip));
1184                         if (err < 0)
1185                                 return err;
1186 
1187                         /* Audio source */
1188                         err = snd_ctl_add(chip->card,
1189                                 snd_ctl_new1(&pcxhr_control_audio_src, chip));
1190                         if (err < 0)
1191                                 return err;
1192 
1193                         /* IEC958 controls */
1194                         err = snd_ctl_add(chip->card,
1195                                 snd_ctl_new1(&pcxhr_control_capture_iec958_mask,
1196                                              chip));
1197                         if (err < 0)
1198                                 return err;
1199 
1200                         err = snd_ctl_add(chip->card,
1201                                 snd_ctl_new1(&pcxhr_control_capture_iec958,
1202                                              chip));
1203                         if (err < 0)
1204                                 return err;
1205 
1206                         if (mgr->is_hr_stereo) {
1207                                 err = hr222_add_mic_controls(chip);
1208                                 if (err < 0)
1209                                         return err;
1210                         }
1211                 }
1212                 /* monitoring only if playback and capture device available */
1213                 if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {
1214                         /* monitoring */
1215                         err = snd_ctl_add(chip->card,
1216                                 snd_ctl_new1(&pcxhr_control_monitor_vol, chip));
1217                         if (err < 0)
1218                                 return err;
1219 
1220                         err = snd_ctl_add(chip->card,
1221                                 snd_ctl_new1(&pcxhr_control_monitor_sw, chip));
1222                         if (err < 0)
1223                                 return err;
1224                 }
1225 
1226                 if (i == 0) {
1227                         /* clock mode only one control per pcxhr */
1228                         err = snd_ctl_add(chip->card,
1229                                 snd_ctl_new1(&pcxhr_control_clock_type, mgr));
1230                         if (err < 0)
1231                                 return err;
1232                         /* non standard control used to scan
1233                          * the external clock presence/frequencies
1234                          */
1235                         err = snd_ctl_add(chip->card,
1236                                 snd_ctl_new1(&pcxhr_control_clock_rate, mgr));
1237                         if (err < 0)
1238                                 return err;
1239                 }
1240 
1241                 /* init values for the mixer data */
1242                 pcxhr_init_audio_levels(chip);
1243         }
1244 
1245         return 0;
1246 }
1247 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php