Linux 2.6.24.5
[linux/fpc-iii.git] / sound / pci / pcxhr / pcxhr_mixer.c
blob5f8d42633b040b92a88b173df5ad4222d2bdcd43
1 #define __NO_VERSION__
2 /*
3 * Driver for Digigram pcxhr compatible soundcards
5 * mixer callbacks
7 * Copyright (c) 2004 by Digigram <alsa@digigram.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <sound/driver.h>
25 #include <linux/time.h>
26 #include <linux/interrupt.h>
27 #include <linux/init.h>
28 #include <linux/mutex.h>
29 #include <sound/core.h>
30 #include "pcxhr.h"
31 #include "pcxhr_hwdep.h"
32 #include "pcxhr_core.h"
33 #include <sound/control.h>
34 #include <sound/tlv.h>
35 #include <sound/asoundef.h>
36 #include "pcxhr_mixer.h"
39 #define PCXHR_ANALOG_CAPTURE_LEVEL_MIN 0 /* -96.0 dB */
40 #define PCXHR_ANALOG_CAPTURE_LEVEL_MAX 255 /* +31.5 dB */
41 #define PCXHR_ANALOG_CAPTURE_ZERO_LEVEL 224 /* +16.0 dB ( +31.5 dB - fix level +15.5 dB ) */
43 #define PCXHR_ANALOG_PLAYBACK_LEVEL_MIN 0 /* -128.0 dB */
44 #define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */
45 #define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */
47 static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 3150);
48 static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
50 static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel)
52 int err, vol;
53 struct pcxhr_rmh rmh;
55 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
56 if (is_capture) {
57 rmh.cmd[0] |= IO_NUM_REG_IN_ANA_LEVEL;
58 rmh.cmd[2] = chip->analog_capture_volume[channel];
59 } else {
60 rmh.cmd[0] |= IO_NUM_REG_OUT_ANA_LEVEL;
61 if (chip->analog_playback_active[channel])
62 vol = chip->analog_playback_volume[channel];
63 else
64 vol = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN;
65 rmh.cmd[2] = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX - vol; /* playback analog levels are inversed */
67 rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */
68 rmh.cmd_len = 3;
69 err = pcxhr_send_msg(chip->mgr, &rmh);
70 if (err < 0) {
71 snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d) "
72 "is_capture(%d) err(%x)\n", chip->chip_idx, is_capture, err);
73 return -EINVAL;
75 return 0;
79 * analog level control
81 static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
82 struct snd_ctl_elem_info *uinfo)
84 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
85 uinfo->count = 2;
86 if (kcontrol->private_value == 0) { /* playback */
87 uinfo->value.integer.min = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN; /* -128 dB */
88 uinfo->value.integer.max = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX; /* 0 dB */
89 } else { /* capture */
90 uinfo->value.integer.min = PCXHR_ANALOG_CAPTURE_LEVEL_MIN; /* -96 dB */
91 uinfo->value.integer.max = PCXHR_ANALOG_CAPTURE_LEVEL_MAX; /* 31.5 dB */
93 return 0;
96 static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
97 struct snd_ctl_elem_value *ucontrol)
99 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
100 mutex_lock(&chip->mgr->mixer_mutex);
101 if (kcontrol->private_value == 0) { /* playback */
102 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
103 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
104 } else { /* capture */
105 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
106 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
108 mutex_unlock(&chip->mgr->mixer_mutex);
109 return 0;
112 static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
113 struct snd_ctl_elem_value *ucontrol)
115 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
116 int changed = 0;
117 int is_capture, i;
119 mutex_lock(&chip->mgr->mixer_mutex);
120 is_capture = (kcontrol->private_value != 0);
121 for (i = 0; i < 2; i++) {
122 int new_volume = ucontrol->value.integer.value[i];
123 int* stored_volume = is_capture ? &chip->analog_capture_volume[i] :
124 &chip->analog_playback_volume[i];
125 if (*stored_volume != new_volume) {
126 *stored_volume = new_volume;
127 changed = 1;
128 pcxhr_update_analog_audio_level(chip, is_capture, i);
131 mutex_unlock(&chip->mgr->mixer_mutex);
132 return changed;
135 static struct snd_kcontrol_new pcxhr_control_analog_level = {
136 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
137 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
138 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
139 /* name will be filled later */
140 .info = pcxhr_analog_vol_info,
141 .get = pcxhr_analog_vol_get,
142 .put = pcxhr_analog_vol_put,
143 /* tlv will be filled later */
146 /* shared */
147 #define pcxhr_sw_info snd_ctl_boolean_stereo_info
149 static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
150 struct snd_ctl_elem_value *ucontrol)
152 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
154 mutex_lock(&chip->mgr->mixer_mutex);
155 ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
156 ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
157 mutex_unlock(&chip->mgr->mixer_mutex);
158 return 0;
161 static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
164 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
165 int i, changed = 0;
166 mutex_lock(&chip->mgr->mixer_mutex);
167 for(i = 0; i < 2; i++) {
168 if (chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) {
169 chip->analog_playback_active[i] = ucontrol->value.integer.value[i];
170 changed = 1;
171 pcxhr_update_analog_audio_level(chip, 0, i); /* update playback levels */
174 mutex_unlock(&chip->mgr->mixer_mutex);
175 return changed;
178 static struct snd_kcontrol_new pcxhr_control_output_switch = {
179 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
180 .name = "Master Playback Switch",
181 .info = pcxhr_sw_info, /* shared */
182 .get = pcxhr_audio_sw_get,
183 .put = pcxhr_audio_sw_put
187 #define PCXHR_DIGITAL_LEVEL_MIN 0x000 /* -110 dB */
188 #define PCXHR_DIGITAL_LEVEL_MAX 0x1ff /* +18 dB */
189 #define PCXHR_DIGITAL_ZERO_LEVEL 0x1b7 /* 0 dB */
191 static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10975, 25, 1800);
193 #define MORE_THAN_ONE_STREAM_LEVEL 0x000001
194 #define VALID_STREAM_PAN_LEVEL_MASK 0x800000
195 #define VALID_STREAM_LEVEL_MASK 0x400000
196 #define VALID_STREAM_LEVEL_1_MASK 0x200000
197 #define VALID_STREAM_LEVEL_2_MASK 0x100000
199 static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
201 int err;
202 struct pcxhr_rmh rmh;
203 struct pcxhr_pipe *pipe = &chip->playback_pipe;
204 int left, right;
206 if (chip->digital_playback_active[idx][0])
207 left = chip->digital_playback_volume[idx][0];
208 else
209 left = PCXHR_DIGITAL_LEVEL_MIN;
210 if (chip->digital_playback_active[idx][1])
211 right = chip->digital_playback_volume[idx][1];
212 else
213 right = PCXHR_DIGITAL_LEVEL_MIN;
215 pcxhr_init_rmh(&rmh, CMD_STREAM_OUT_LEVEL_ADJUST);
216 /* add pipe and stream mask */
217 pcxhr_set_pipe_cmd_params(&rmh, 0, pipe->first_audio, 0, 1<<idx);
218 /* volume left->left / right->right panoramic level */
219 rmh.cmd[0] |= MORE_THAN_ONE_STREAM_LEVEL;
220 rmh.cmd[2] = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_1_MASK;
221 rmh.cmd[2] |= (left << 10);
222 rmh.cmd[3] = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_2_MASK;
223 rmh.cmd[3] |= right;
224 rmh.cmd_len = 4;
226 err = pcxhr_send_msg(chip->mgr, &rmh);
227 if (err < 0) {
228 snd_printk(KERN_DEBUG "error update_playback_stream_level "
229 "card(%d) err(%x)\n", chip->chip_idx, err);
230 return -EINVAL;
232 return 0;
235 #define AUDIO_IO_HAS_MUTE_LEVEL 0x400000
236 #define AUDIO_IO_HAS_MUTE_MONITOR_1 0x200000
237 #define VALID_AUDIO_IO_DIGITAL_LEVEL 0x000001
238 #define VALID_AUDIO_IO_MONITOR_LEVEL 0x000002
239 #define VALID_AUDIO_IO_MUTE_LEVEL 0x000004
240 #define VALID_AUDIO_IO_MUTE_MONITOR_1 0x000008
242 static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, int channel)
244 int err;
245 struct pcxhr_rmh rmh;
246 struct pcxhr_pipe *pipe;
248 if (capture)
249 pipe = &chip->capture_pipe[0];
250 else
251 pipe = &chip->playback_pipe;
253 pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
254 /* add channel mask */
255 pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0, 1 << (channel + pipe->first_audio));
256 /* TODO : if mask (3 << pipe->first_audio) is used, left and right channel
257 * will be programmed to the same params
259 if (capture) {
260 rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
261 /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled (capture pipe level) */
262 rmh.cmd[2] = chip->digital_capture_volume[channel];
263 } else {
264 rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL | VALID_AUDIO_IO_MUTE_MONITOR_1;
265 /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL not yet
266 * handled (playback pipe level)
268 rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
269 if (chip->monitoring_active[channel] == 0)
270 rmh.cmd[2] |= AUDIO_IO_HAS_MUTE_MONITOR_1;
272 rmh.cmd_len = 3;
274 err = pcxhr_send_msg(chip->mgr, &rmh);
275 if(err<0) {
276 snd_printk(KERN_DEBUG "error update_audio_level card(%d) err(%x)\n",
277 chip->chip_idx, err);
278 return -EINVAL;
280 return 0;
284 /* shared */
285 static int pcxhr_digital_vol_info(struct snd_kcontrol *kcontrol,
286 struct snd_ctl_elem_info *uinfo)
288 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
289 uinfo->count = 2;
290 uinfo->value.integer.min = PCXHR_DIGITAL_LEVEL_MIN; /* -109.5 dB */
291 uinfo->value.integer.max = PCXHR_DIGITAL_LEVEL_MAX; /* 18.0 dB */
292 return 0;
296 static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
297 struct snd_ctl_elem_value *ucontrol)
299 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
300 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
301 int *stored_volume;
302 int is_capture = kcontrol->private_value;
304 mutex_lock(&chip->mgr->mixer_mutex);
305 if (is_capture)
306 stored_volume = chip->digital_capture_volume; /* digital capture */
307 else
308 stored_volume = chip->digital_playback_volume[idx]; /* digital playback */
309 ucontrol->value.integer.value[0] = stored_volume[0];
310 ucontrol->value.integer.value[1] = stored_volume[1];
311 mutex_unlock(&chip->mgr->mixer_mutex);
312 return 0;
315 static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
316 struct snd_ctl_elem_value *ucontrol)
318 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
319 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
320 int changed = 0;
321 int is_capture = kcontrol->private_value;
322 int *stored_volume;
323 int i;
325 mutex_lock(&chip->mgr->mixer_mutex);
326 if (is_capture)
327 stored_volume = chip->digital_capture_volume; /* digital capture */
328 else
329 stored_volume = chip->digital_playback_volume[idx]; /* digital playback */
330 for (i = 0; i < 2; i++) {
331 if (stored_volume[i] != ucontrol->value.integer.value[i]) {
332 stored_volume[i] = ucontrol->value.integer.value[i];
333 changed = 1;
334 if (is_capture) /* update capture volume */
335 pcxhr_update_audio_pipe_level(chip, 1, i);
338 if (! is_capture && changed)
339 pcxhr_update_playback_stream_level(chip, idx); /* update playback volume */
340 mutex_unlock(&chip->mgr->mixer_mutex);
341 return changed;
344 static struct snd_kcontrol_new snd_pcxhr_pcm_vol =
346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
347 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
348 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
349 /* name will be filled later */
350 /* count will be filled later */
351 .info = pcxhr_digital_vol_info, /* shared */
352 .get = pcxhr_pcm_vol_get,
353 .put = pcxhr_pcm_vol_put,
354 .tlv = { .p = db_scale_digital },
358 static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
359 struct snd_ctl_elem_value *ucontrol)
361 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
362 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
364 mutex_lock(&chip->mgr->mixer_mutex);
365 ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
366 ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
367 mutex_unlock(&chip->mgr->mixer_mutex);
368 return 0;
371 static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
373 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
374 int changed = 0;
375 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
376 int i, j;
378 mutex_lock(&chip->mgr->mixer_mutex);
379 j = idx;
380 for (i = 0; i < 2; i++) {
381 if (chip->digital_playback_active[j][i] != ucontrol->value.integer.value[i]) {
382 chip->digital_playback_active[j][i] = ucontrol->value.integer.value[i];
383 changed = 1;
386 if (changed)
387 pcxhr_update_playback_stream_level(chip, idx);
388 mutex_unlock(&chip->mgr->mixer_mutex);
389 return changed;
392 static struct snd_kcontrol_new pcxhr_control_pcm_switch = {
393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
394 .name = "PCM Playback Switch",
395 .count = PCXHR_PLAYBACK_STREAMS,
396 .info = pcxhr_sw_info, /* shared */
397 .get = pcxhr_pcm_sw_get,
398 .put = pcxhr_pcm_sw_put
403 * monitoring level control
406 static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol,
407 struct snd_ctl_elem_value *ucontrol)
409 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
410 mutex_lock(&chip->mgr->mixer_mutex);
411 ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
412 ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
413 mutex_unlock(&chip->mgr->mixer_mutex);
414 return 0;
417 static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
418 struct snd_ctl_elem_value *ucontrol)
420 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
421 int changed = 0;
422 int i;
424 mutex_lock(&chip->mgr->mixer_mutex);
425 for (i = 0; i < 2; i++) {
426 if (chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) {
427 chip->monitoring_volume[i] = ucontrol->value.integer.value[i];
428 if(chip->monitoring_active[i]) /* do only when monitoring is unmuted */
429 /* update monitoring volume and mute */
430 pcxhr_update_audio_pipe_level(chip, 0, i);
431 changed = 1;
434 mutex_unlock(&chip->mgr->mixer_mutex);
435 return changed;
438 static struct snd_kcontrol_new pcxhr_control_monitor_vol = {
439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
440 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
441 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
442 .name = "Monitoring Volume",
443 .info = pcxhr_digital_vol_info, /* shared */
444 .get = pcxhr_monitor_vol_get,
445 .put = pcxhr_monitor_vol_put,
446 .tlv = { .p = db_scale_digital },
450 * monitoring switch control
453 static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
456 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
457 mutex_lock(&chip->mgr->mixer_mutex);
458 ucontrol->value.integer.value[0] = chip->monitoring_active[0];
459 ucontrol->value.integer.value[1] = chip->monitoring_active[1];
460 mutex_unlock(&chip->mgr->mixer_mutex);
461 return 0;
464 static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
465 struct snd_ctl_elem_value *ucontrol)
467 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
468 int changed = 0;
469 int i;
471 mutex_lock(&chip->mgr->mixer_mutex);
472 for (i = 0; i < 2; i++) {
473 if (chip->monitoring_active[i] != ucontrol->value.integer.value[i]) {
474 chip->monitoring_active[i] = ucontrol->value.integer.value[i];
475 changed |= (1<<i); /* mask 0x01 and 0x02 */
478 if(changed & 0x01)
479 /* update left monitoring volume and mute */
480 pcxhr_update_audio_pipe_level(chip, 0, 0);
481 if(changed & 0x02)
482 /* update right monitoring volume and mute */
483 pcxhr_update_audio_pipe_level(chip, 0, 1);
485 mutex_unlock(&chip->mgr->mixer_mutex);
486 return (changed != 0);
489 static struct snd_kcontrol_new pcxhr_control_monitor_sw = {
490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
491 .name = "Monitoring Switch",
492 .info = pcxhr_sw_info, /* shared */
493 .get = pcxhr_monitor_sw_get,
494 .put = pcxhr_monitor_sw_put
500 * audio source select
502 #define PCXHR_SOURCE_AUDIO01_UER 0x000100
503 #define PCXHR_SOURCE_AUDIO01_SYNC 0x000200
504 #define PCXHR_SOURCE_AUDIO23_UER 0x000400
505 #define PCXHR_SOURCE_AUDIO45_UER 0x001000
506 #define PCXHR_SOURCE_AUDIO67_UER 0x040000
508 static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
510 struct pcxhr_rmh rmh;
511 unsigned int mask, reg;
512 unsigned int codec;
513 int err, use_src, changed;
515 switch (chip->chip_idx) {
516 case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
517 case 1 : mask = PCXHR_SOURCE_AUDIO23_UER; codec = CS8420_23_CS; break;
518 case 2 : mask = PCXHR_SOURCE_AUDIO45_UER; codec = CS8420_45_CS; break;
519 case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
520 default: return -EINVAL;
522 reg = 0; /* audio source from analog plug */
523 use_src = 0; /* do not activate codec SRC */
525 if (chip->audio_capture_source != 0) {
526 reg = mask; /* audio source from digital plug */
527 if (chip->audio_capture_source == 2)
528 use_src = 1;
530 /* set the input source */
531 pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
532 /* resync them (otherwise channel inversion possible) */
533 if (changed) {
534 pcxhr_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
535 rmh.cmd[0] |= (1 << chip->chip_idx);
536 err = pcxhr_send_msg(chip->mgr, &rmh);
537 if (err)
538 return err;
540 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set codec SRC on off */
541 rmh.cmd_len = 3;
542 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
543 rmh.cmd[1] = codec;
544 rmh.cmd[2] = (CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x54);
545 err = pcxhr_send_msg(chip->mgr, &rmh);
546 if(err)
547 return err;
548 rmh.cmd[2] = (CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x49);
549 err = pcxhr_send_msg(chip->mgr, &rmh);
550 return err;
553 static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
554 struct snd_ctl_elem_info *uinfo)
556 static char *texts[3] = {"Analog", "Digital", "Digi+SRC"};
558 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
559 uinfo->count = 1;
560 uinfo->value.enumerated.items = 3;
561 if (uinfo->value.enumerated.item > 2)
562 uinfo->value.enumerated.item = 2;
563 strcpy(uinfo->value.enumerated.name,
564 texts[uinfo->value.enumerated.item]);
565 return 0;
568 static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol,
569 struct snd_ctl_elem_value *ucontrol)
571 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
572 ucontrol->value.enumerated.item[0] = chip->audio_capture_source;
573 return 0;
576 static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_value *ucontrol)
579 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
580 int ret = 0;
582 mutex_lock(&chip->mgr->mixer_mutex);
583 if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
584 chip->audio_capture_source = ucontrol->value.enumerated.item[0];
585 pcxhr_set_audio_source(chip);
586 ret = 1;
588 mutex_unlock(&chip->mgr->mixer_mutex);
589 return ret;
592 static struct snd_kcontrol_new pcxhr_control_audio_src = {
593 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
594 .name = "Capture Source",
595 .info = pcxhr_audio_src_info,
596 .get = pcxhr_audio_src_get,
597 .put = pcxhr_audio_src_put,
602 * clock type selection
603 * enum pcxhr_clock_type {
604 * PCXHR_CLOCK_TYPE_INTERNAL = 0,
605 * PCXHR_CLOCK_TYPE_WORD_CLOCK,
606 * PCXHR_CLOCK_TYPE_AES_SYNC,
607 * PCXHR_CLOCK_TYPE_AES_1,
608 * PCXHR_CLOCK_TYPE_AES_2,
609 * PCXHR_CLOCK_TYPE_AES_3,
610 * PCXHR_CLOCK_TYPE_AES_4,
611 * };
614 static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_info *uinfo)
617 static char *texts[7] = {
618 "Internal", "WordClock", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4"
620 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
621 int clock_items = 3 + mgr->capture_chips;
623 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
624 uinfo->count = 1;
625 uinfo->value.enumerated.items = clock_items;
626 if (uinfo->value.enumerated.item >= clock_items)
627 uinfo->value.enumerated.item = clock_items-1;
628 strcpy(uinfo->value.enumerated.name,
629 texts[uinfo->value.enumerated.item]);
630 return 0;
633 static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol,
634 struct snd_ctl_elem_value *ucontrol)
636 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
637 ucontrol->value.enumerated.item[0] = mgr->use_clock_type;
638 return 0;
641 static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
642 struct snd_ctl_elem_value *ucontrol)
644 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
645 int rate, ret = 0;
647 mutex_lock(&mgr->mixer_mutex);
648 if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) {
649 mutex_lock(&mgr->setup_mutex);
650 mgr->use_clock_type = ucontrol->value.enumerated.item[0];
651 if (mgr->use_clock_type)
652 pcxhr_get_external_clock(mgr, mgr->use_clock_type, &rate);
653 else
654 rate = mgr->sample_rate;
655 if (rate) {
656 pcxhr_set_clock(mgr, rate);
657 if (mgr->sample_rate)
658 mgr->sample_rate = rate;
660 mutex_unlock(&mgr->setup_mutex);
661 ret = 1; /* return 1 even if the set was not done. ok ? */
663 mutex_unlock(&mgr->mixer_mutex);
664 return ret;
667 static struct snd_kcontrol_new pcxhr_control_clock_type = {
668 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
669 .name = "Clock Mode",
670 .info = pcxhr_clock_type_info,
671 .get = pcxhr_clock_type_get,
672 .put = pcxhr_clock_type_put,
676 * clock rate control
677 * specific control that scans the sample rates on the external plugs
679 static int pcxhr_clock_rate_info(struct snd_kcontrol *kcontrol,
680 struct snd_ctl_elem_info *uinfo)
682 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
683 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
684 uinfo->count = 3 + mgr->capture_chips;
685 uinfo->value.integer.min = 0; /* clock not present */
686 uinfo->value.integer.max = 192000; /* max sample rate 192 kHz */
687 return 0;
690 static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
691 struct snd_ctl_elem_value *ucontrol)
693 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
694 int i, err, rate;
696 mutex_lock(&mgr->mixer_mutex);
697 for(i = 0; i < 3 + mgr->capture_chips; i++) {
698 if (i == PCXHR_CLOCK_TYPE_INTERNAL)
699 rate = mgr->sample_rate_real;
700 else {
701 err = pcxhr_get_external_clock(mgr, i, &rate);
702 if (err)
703 break;
705 ucontrol->value.integer.value[i] = rate;
707 mutex_unlock(&mgr->mixer_mutex);
708 return 0;
711 static struct snd_kcontrol_new pcxhr_control_clock_rate = {
712 .access = SNDRV_CTL_ELEM_ACCESS_READ,
713 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
714 .name = "Clock Rates",
715 .info = pcxhr_clock_rate_info,
716 .get = pcxhr_clock_rate_get,
720 * IEC958 status bits
722 static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
724 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
725 uinfo->count = 1;
726 return 0;
729 static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char* aes_bits)
731 int i, err;
732 unsigned char temp;
733 struct pcxhr_rmh rmh;
735 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
736 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
737 switch (chip->chip_idx) {
738 case 0: rmh.cmd[1] = CS8420_01_CS; break; /* use CS8416_01_CS for AES SYNC plug */
739 case 1: rmh.cmd[1] = CS8420_23_CS; break;
740 case 2: rmh.cmd[1] = CS8420_45_CS; break;
741 case 3: rmh.cmd[1] = CS8420_67_CS; break;
742 default: return -EINVAL;
744 switch (aes_idx) {
745 case 0: rmh.cmd[2] = CS8420_CSB0; break; /* use CS8416_CSBx for AES SYNC plug */
746 case 1: rmh.cmd[2] = CS8420_CSB1; break;
747 case 2: rmh.cmd[2] = CS8420_CSB2; break;
748 case 3: rmh.cmd[2] = CS8420_CSB3; break;
749 case 4: rmh.cmd[2] = CS8420_CSB4; break;
750 default: return -EINVAL;
752 rmh.cmd[1] &= 0x0fffff; /* size and code the chip id for the fpga */
753 rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI; /* chip signature + map for spi read */
754 rmh.cmd_len = 3;
755 err = pcxhr_send_msg(chip->mgr, &rmh);
756 if (err)
757 return err;
758 temp = 0;
759 for (i = 0; i < 8; i++) {
760 /* attention : reversed bit order (not with CS8416_01_CS) */
761 temp <<= 1;
762 if (rmh.stat[1] & (1 << i))
763 temp |= 1;
765 snd_printdd("read iec958 AES %d byte %d = 0x%x\n", chip->chip_idx, aes_idx, temp);
766 *aes_bits = temp;
767 return 0;
770 static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
772 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
773 unsigned char aes_bits;
774 int i, err;
776 mutex_lock(&chip->mgr->mixer_mutex);
777 for(i = 0; i < 5; i++) {
778 if (kcontrol->private_value == 0) /* playback */
779 aes_bits = chip->aes_bits[i];
780 else { /* capture */
781 err = pcxhr_iec958_capture_byte(chip, i, &aes_bits);
782 if (err)
783 break;
785 ucontrol->value.iec958.status[i] = aes_bits;
787 mutex_unlock(&chip->mgr->mixer_mutex);
788 return 0;
791 static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
792 struct snd_ctl_elem_value *ucontrol)
794 int i;
795 for (i = 0; i < 5; i++)
796 ucontrol->value.iec958.status[i] = 0xff;
797 return 0;
800 static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char aes_bits)
802 int i, err, cmd;
803 unsigned char new_bits = aes_bits;
804 unsigned char old_bits = chip->aes_bits[aes_idx];
805 struct pcxhr_rmh rmh;
807 for (i = 0; i < 8; i++) {
808 if ((old_bits & 0x01) != (new_bits & 0x01)) {
809 cmd = chip->chip_idx & 0x03; /* chip index 0..3 */
810 if(chip->chip_idx > 3)
811 /* new bit used if chip_idx>3 (PCX1222HR) */
812 cmd |= 1 << 22;
813 cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */
814 cmd |= (new_bits & 0x01) << 23; /* add bit value */
815 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
816 rmh.cmd[0] |= IO_NUM_REG_CUER;
817 rmh.cmd[1] = cmd;
818 rmh.cmd_len = 2;
819 snd_printdd("write iec958 AES %d byte %d bit %d (cmd %x)\n",
820 chip->chip_idx, aes_idx, i, cmd);
821 err = pcxhr_send_msg(chip->mgr, &rmh);
822 if (err)
823 return err;
825 old_bits >>= 1;
826 new_bits >>= 1;
828 chip->aes_bits[aes_idx] = aes_bits;
829 return 0;
832 static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
833 struct snd_ctl_elem_value *ucontrol)
835 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
836 int i, changed = 0;
838 /* playback */
839 mutex_lock(&chip->mgr->mixer_mutex);
840 for (i = 0; i < 5; i++) {
841 if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
842 pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]);
843 changed = 1;
846 mutex_unlock(&chip->mgr->mixer_mutex);
847 return changed;
850 static struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = {
851 .access = SNDRV_CTL_ELEM_ACCESS_READ,
852 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
853 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
854 .info = pcxhr_iec958_info,
855 .get = pcxhr_iec958_mask_get
857 static struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
858 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
859 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
860 .info = pcxhr_iec958_info,
861 .get = pcxhr_iec958_get,
862 .put = pcxhr_iec958_put,
863 .private_value = 0 /* playback */
866 static struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = {
867 .access = SNDRV_CTL_ELEM_ACCESS_READ,
868 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
869 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
870 .info = pcxhr_iec958_info,
871 .get = pcxhr_iec958_mask_get
873 static struct snd_kcontrol_new pcxhr_control_capture_iec958 = {
874 .access = SNDRV_CTL_ELEM_ACCESS_READ,
875 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
876 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
877 .info = pcxhr_iec958_info,
878 .get = pcxhr_iec958_get,
879 .private_value = 1 /* capture */
882 static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
884 int i;
886 for (i = 0; i < 2; i++) {
887 if (chip->nb_streams_play) {
888 int j;
889 /* at boot time the digital volumes are unmuted 0dB */
890 for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {
891 chip->digital_playback_active[j][i] = 1;
892 chip->digital_playback_volume[j][i] = PCXHR_DIGITAL_ZERO_LEVEL;
894 /* after boot, only two bits are set on the uer interface */
895 chip->aes_bits[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_FS_48000;
896 /* only for test purpose, remove later */
897 #ifdef CONFIG_SND_DEBUG
898 /* analog volumes for playback (is LEVEL_MIN after boot) */
899 chip->analog_playback_active[i] = 1;
900 chip->analog_playback_volume[i] = PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL;
901 pcxhr_update_analog_audio_level(chip, 0, i);
902 #endif
903 /* test end */
905 if (chip->nb_streams_capt) {
906 /* at boot time the digital volumes are unmuted 0dB */
907 chip->digital_capture_volume[i] = PCXHR_DIGITAL_ZERO_LEVEL;
908 /* only for test purpose, remove later */
909 #ifdef CONFIG_SND_DEBUG
910 /* analog volumes for playback (is LEVEL_MIN after boot) */
911 chip->analog_capture_volume[i] = PCXHR_ANALOG_CAPTURE_ZERO_LEVEL;
912 pcxhr_update_analog_audio_level(chip, 1, i);
913 #endif
914 /* test end */
918 return;
922 int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
924 struct snd_pcxhr *chip;
925 int err, i;
927 mutex_init(&mgr->mixer_mutex); /* can be in another place */
929 for (i = 0; i < mgr->num_cards; i++) {
930 struct snd_kcontrol_new temp;
931 chip = mgr->chip[i];
933 if (chip->nb_streams_play) {
934 /* analog output level control */
935 temp = pcxhr_control_analog_level;
936 temp.name = "Master Playback Volume";
937 temp.private_value = 0; /* playback */
938 temp.tlv.p = db_scale_analog_playback;
939 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
940 return err;
941 /* output mute controls */
942 if ((err = snd_ctl_add(chip->card,
943 snd_ctl_new1(&pcxhr_control_output_switch,
944 chip))) < 0)
945 return err;
947 temp = snd_pcxhr_pcm_vol;
948 temp.name = "PCM Playback Volume";
949 temp.count = PCXHR_PLAYBACK_STREAMS;
950 temp.private_value = 0; /* playback */
951 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
952 return err;
954 if ((err = snd_ctl_add(chip->card,
955 snd_ctl_new1(&pcxhr_control_pcm_switch,
956 chip))) < 0)
957 return err;
959 /* IEC958 controls */
960 if ((err = snd_ctl_add(chip->card,
961 snd_ctl_new1(&pcxhr_control_playback_iec958_mask,
962 chip))) < 0)
963 return err;
964 if ((err = snd_ctl_add(chip->card,
965 snd_ctl_new1(&pcxhr_control_playback_iec958,
966 chip))) < 0)
967 return err;
969 if (chip->nb_streams_capt) {
970 /* analog input level control only on first two chips !*/
971 temp = pcxhr_control_analog_level;
972 temp.name = "Master Capture Volume";
973 temp.private_value = 1; /* capture */
974 temp.tlv.p = db_scale_analog_capture;
975 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
976 return err;
978 temp = snd_pcxhr_pcm_vol;
979 temp.name = "PCM Capture Volume";
980 temp.count = 1;
981 temp.private_value = 1; /* capture */
982 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
983 return err;
984 /* Audio source */
985 if ((err = snd_ctl_add(chip->card,
986 snd_ctl_new1(&pcxhr_control_audio_src,
987 chip))) < 0)
988 return err;
989 /* IEC958 controls */
990 if ((err = snd_ctl_add(chip->card,
991 snd_ctl_new1(&pcxhr_control_capture_iec958_mask,
992 chip))) < 0)
993 return err;
994 if ((err = snd_ctl_add(chip->card,
995 snd_ctl_new1(&pcxhr_control_capture_iec958,
996 chip))) < 0)
997 return err;
999 /* monitoring only if playback and capture device available */
1000 if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {
1001 /* monitoring */
1002 if ((err = snd_ctl_add(chip->card,
1003 snd_ctl_new1(&pcxhr_control_monitor_vol,
1004 chip))) < 0)
1005 return err;
1006 if ((err = snd_ctl_add(chip->card,
1007 snd_ctl_new1(&pcxhr_control_monitor_sw,
1008 chip))) < 0)
1009 return err;
1012 if (i == 0) {
1013 /* clock mode only one control per pcxhr */
1014 if ((err = snd_ctl_add(chip->card,
1015 snd_ctl_new1(&pcxhr_control_clock_type,
1016 mgr))) < 0)
1017 return err;
1018 /* non standard control used to scan the external clock presence/frequencies */
1019 if ((err = snd_ctl_add(chip->card,
1020 snd_ctl_new1(&pcxhr_control_clock_rate,
1021 mgr))) < 0)
1022 return err;
1025 /* init values for the mixer data */
1026 pcxhr_init_audio_levels(chip);
1029 return 0;