OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [sound/] [pci/] [pcxhr/] [pcxhr_mixer.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
#define __NO_VERSION__
2
/*
3
 * Driver for Digigram pcxhr compatible soundcards
4
 *
5
 * mixer callbacks
6
 *
7
 * Copyright (c) 2004 by Digigram <alsa@digigram.com>
8
 *
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.
13
 *
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.
18
 *
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
22
 */
23
 
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"
37
 
38
 
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 ) */
42
 
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 ) */
46
 
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);
49
 
50
static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel)
51
{
52
        int err, vol;
53
        struct pcxhr_rmh rmh;
54
 
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 */
66
        }
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;
74
        }
75
        return 0;
76
}
77
 
78
/*
79
 * analog level control
80
 */
81
static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
82
                                 struct snd_ctl_elem_info *uinfo)
83
{
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 */
92
        }
93
        return 0;
94
}
95
 
96
static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
97
                                struct snd_ctl_elem_value *ucontrol)
98
{
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];
107
        }
108
        mutex_unlock(&chip->mgr->mixer_mutex);
109
        return 0;
110
}
111
 
112
static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
113
                                struct snd_ctl_elem_value *ucontrol)
114
{
115
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
116
        int changed = 0;
117
        int is_capture, i;
118
 
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);
129
                }
130
        }
131
        mutex_unlock(&chip->mgr->mixer_mutex);
132
        return changed;
133
}
134
 
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 */
144
};
145
 
146
/* shared */
147
#define pcxhr_sw_info           snd_ctl_boolean_stereo_info
148
 
149
static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
150
                              struct snd_ctl_elem_value *ucontrol)
151
{
152
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
153
 
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;
159
}
160
 
161
static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
162
                              struct snd_ctl_elem_value *ucontrol)
163
{
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 */
172
                }
173
        }
174
        mutex_unlock(&chip->mgr->mixer_mutex);
175
        return changed;
176
}
177
 
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
184
};
185
 
186
 
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 */
190
 
191
static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10975, 25, 1800);
192
 
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
198
 
199
static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
200
{
201
        int err;
202
        struct pcxhr_rmh rmh;
203
        struct pcxhr_pipe *pipe = &chip->playback_pipe;
204
        int left, right;
205
 
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;
214
 
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;
225
 
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;
231
        }
232
        return 0;
233
}
234
 
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
241
 
242
static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, int channel)
243
{
244
        int err;
245
        struct pcxhr_rmh rmh;
246
        struct pcxhr_pipe *pipe;
247
 
248
        if (capture)
249
                pipe = &chip->capture_pipe[0];
250
        else
251
                pipe = &chip->playback_pipe;
252
 
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
258
         */
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)
267
                 */
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;
271
        }
272
        rmh.cmd_len = 3;
273
 
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;
279
        }
280
        return 0;
281
}
282
 
283
 
284
/* shared */
285
static int pcxhr_digital_vol_info(struct snd_kcontrol *kcontrol,
286
                                  struct snd_ctl_elem_info *uinfo)
287
{
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;
293
}
294
 
295
 
296
static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
297
                             struct snd_ctl_elem_value *ucontrol)
298
{
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;
303
 
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;
313
}
314
 
315
static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
316
                             struct snd_ctl_elem_value *ucontrol)
317
{
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;
324
 
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);
336
                }
337
        }
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;
342
}
343
 
344
static struct snd_kcontrol_new snd_pcxhr_pcm_vol =
345
{
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 },
355
};
356
 
357
 
358
static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
359
                            struct snd_ctl_elem_value *ucontrol)
360
{
361
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
362
        int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
363
 
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;
369
}
370
 
371
static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
372
{
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;
377
 
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;
384
                }
385
        }
386
        if (changed)
387
                pcxhr_update_playback_stream_level(chip, idx);
388
        mutex_unlock(&chip->mgr->mixer_mutex);
389
        return changed;
390
}
391
 
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
399
};
400
 
401
 
402
/*
403
 * monitoring level control
404
 */
405
 
406
static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol,
407
                                 struct snd_ctl_elem_value *ucontrol)
408
{
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;
415
}
416
 
417
static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
418
                                 struct snd_ctl_elem_value *ucontrol)
419
{
420
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
421
        int changed = 0;
422
        int i;
423
 
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;
432
                }
433
        }
434
        mutex_unlock(&chip->mgr->mixer_mutex);
435
        return changed;
436
}
437
 
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 },
447
};
448
 
449
/*
450
 * monitoring switch control
451
 */
452
 
453
static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol,
454
                                struct snd_ctl_elem_value *ucontrol)
455
{
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;
462
}
463
 
464
static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
465
                                struct snd_ctl_elem_value *ucontrol)
466
{
467
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
468
        int changed = 0;
469
        int i;
470
 
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 */
476
                }
477
        }
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);
484
 
485
        mutex_unlock(&chip->mgr->mixer_mutex);
486
        return (changed != 0);
487
}
488
 
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
495
};
496
 
497
 
498
 
499
/*
500
 * audio source select
501
 */
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
507
 
508
static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
509
{
510
        struct pcxhr_rmh rmh;
511
        unsigned int mask, reg;
512
        unsigned int codec;
513
        int err, use_src, changed;
514
 
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;
521
        }
522
        reg = 0; /* audio source from analog plug */
523
        use_src = 0;     /* do not activate codec SRC */
524
 
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;
529
        }
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;
539
        }
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;
551
}
552
 
553
static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
554
                                struct snd_ctl_elem_info *uinfo)
555
{
556
        static char *texts[3] = {"Analog", "Digital", "Digi+SRC"};
557
 
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;
566
}
567
 
568
static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol,
569
                               struct snd_ctl_elem_value *ucontrol)
570
{
571
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
572
        ucontrol->value.enumerated.item[0] = chip->audio_capture_source;
573
        return 0;
574
}
575
 
576
static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
577
                               struct snd_ctl_elem_value *ucontrol)
578
{
579
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
580
        int ret = 0;
581
 
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;
587
        }
588
        mutex_unlock(&chip->mgr->mixer_mutex);
589
        return ret;
590
}
591
 
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,
598
};
599
 
600
 
601
/*
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
 *      };
612
 */
613
 
614
static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
615
                                 struct snd_ctl_elem_info *uinfo)
616
{
617
        static char *texts[7] = {
618
                "Internal", "WordClock", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4"
619
        };
620
        struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
621
        int clock_items = 3 + mgr->capture_chips;
622
 
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;
631
}
632
 
633
static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol,
634
                                struct snd_ctl_elem_value *ucontrol)
635
{
636
        struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
637
        ucontrol->value.enumerated.item[0] = mgr->use_clock_type;
638
        return 0;
639
}
640
 
641
static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
642
                                struct snd_ctl_elem_value *ucontrol)
643
{
644
        struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
645
        int rate, ret = 0;
646
 
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;
659
                }
660
                mutex_unlock(&mgr->setup_mutex);
661
                ret = 1;        /* return 1 even if the set was not done. ok ? */
662
        }
663
        mutex_unlock(&mgr->mixer_mutex);
664
        return ret;
665
}
666
 
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,
673
};
674
 
675
/*
676
 * clock rate control
677
 * specific control that scans the sample rates on the external plugs
678
 */
679
static int pcxhr_clock_rate_info(struct snd_kcontrol *kcontrol,
680
                                 struct snd_ctl_elem_info *uinfo)
681
{
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;
688
}
689
 
690
static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
691
                                struct snd_ctl_elem_value *ucontrol)
692
{
693
        struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
694
        int i, err, rate;
695
 
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;
704
                }
705
                ucontrol->value.integer.value[i] = rate;
706
        }
707
        mutex_unlock(&mgr->mixer_mutex);
708
        return 0;
709
}
710
 
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,
717
};
718
 
719
/*
720
 * IEC958 status bits
721
 */
722
static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
723
{
724
        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
725
        uinfo->count = 1;
726
        return 0;
727
}
728
 
729
static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char* aes_bits)
730
{
731
        int i, err;
732
        unsigned char temp;
733
        struct pcxhr_rmh rmh;
734
 
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;
743
        }
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;
751
        }
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;
764
        }
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;
768
}
769
 
770
static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
771
{
772
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
773
        unsigned char aes_bits;
774
        int i, err;
775
 
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;
784
                }
785
                ucontrol->value.iec958.status[i] = aes_bits;
786
        }
787
        mutex_unlock(&chip->mgr->mixer_mutex);
788
        return 0;
789
}
790
 
791
static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
792
                                 struct snd_ctl_elem_value *ucontrol)
793
{
794
        int i;
795
        for (i = 0; i < 5; i++)
796
                ucontrol->value.iec958.status[i] = 0xff;
797
        return 0;
798
}
799
 
800
static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char aes_bits)
801
{
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;
806
 
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;
824
                }
825
                old_bits >>= 1;
826
                new_bits >>= 1;
827
        }
828
        chip->aes_bits[aes_idx] = aes_bits;
829
        return 0;
830
}
831
 
832
static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
833
                            struct snd_ctl_elem_value *ucontrol)
834
{
835
        struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
836
        int i, changed = 0;
837
 
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;
844
                }
845
        }
846
        mutex_unlock(&chip->mgr->mixer_mutex);
847
        return changed;
848
}
849
 
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
856
};
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 */
864
};
865
 
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
872
};
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 */
880
};
881
 
882
static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
883
{
884
        int i;
885
 
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;
893
                        }
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 */
904
                }
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 */
915
                }
916
        }
917
 
918
        return;
919
}
920
 
921
 
922
int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
923
{
924
        struct snd_pcxhr *chip;
925
        int err, i;
926
 
927
        mutex_init(&mgr->mixer_mutex); /* can be in another place */
928
 
929
        for (i = 0; i < mgr->num_cards; i++) {
930
                struct snd_kcontrol_new temp;
931
                chip = mgr->chip[i];
932
 
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;
946
 
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;
953
 
954
                        if ((err = snd_ctl_add(chip->card,
955
                                               snd_ctl_new1(&pcxhr_control_pcm_switch,
956
                                                            chip))) < 0)
957
                                return err;
958
 
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;
968
                }
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;
977
 
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;
998
                }
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;
1010
                }
1011
 
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;
1023
                }
1024
 
1025
                /* init values for the mixer data */
1026
                pcxhr_init_audio_levels(chip);
1027
        }
1028
 
1029
        return 0;
1030
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.