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