2
* Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3
* Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
6
* FEATURES currently supported:
7
* See ca0106_main.c for features.
10
* Support interrupts per period.
11
* Removed noise from Center/LFE channel when in Analog mode.
12
* Rename and remove mixer controls.
14
* Use separate card based DMA buffer for periods table list.
16
* Change remove and rename ctrls into lists.
18
* Try to fix capture sources.
21
* Enable S32_LE format support.
23
* Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
25
* Add Model name recognition.
27
* Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
28
* Remove redundent "voice" handling.
30
* Single trigger call for multi channels.
32
* Set limits based on what the sound card hardware can do.
33
* playback periods_min=2, periods_max=8
34
* capture hw constraints require period_size = n * 64 bytes.
35
* playback hw constraints require period_size = n * 64 bytes.
37
* Separated ca0106.c into separate functional .c files.
39
* Modified Copyright message.
41
* Implement Mic and Line in Capture.
43
* Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
45
* This code was initially based on code from ALSA's emu10k1x.c which is:
46
* Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
48
* This program is free software; you can redistribute it and/or modify
49
* it under the terms of the GNU General Public License as published by
50
* the Free Software Foundation; either version 2 of the License, or
51
* (at your option) any later version.
53
* This program is distributed in the hope that it will be useful,
54
* but WITHOUT ANY WARRANTY; without even the implied warranty of
55
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56
* GNU General Public License for more details.
58
* You should have received a copy of the GNU General Public License
59
* along with this program; if not, write to the Free Software
60
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
63
#include <linux/delay.h>
64
#include <linux/init.h>
65
#include <linux/interrupt.h>
66
#include <linux/moduleparam.h>
67
#include <sound/core.h>
68
#include <sound/initval.h>
69
#include <sound/pcm.h>
70
#include <sound/ac97_codec.h>
71
#include <sound/info.h>
72
#include <sound/tlv.h>
77
static void ca0106_spdif_enable(struct snd_ca0106 *emu)
81
if (emu->spdif_enable) {
83
snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
84
snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
85
val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
86
snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
87
val = inl(emu->port + GPIO) & ~0x101;
88
outl(val, emu->port + GPIO);
92
snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
93
snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
94
val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
95
snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
96
val = inl(emu->port + GPIO) | 0x101;
97
outl(val, emu->port + GPIO);
101
static void ca0106_set_capture_source(struct snd_ca0106 *emu)
103
unsigned int val = emu->capture_source;
104
unsigned int source, mask;
105
source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
106
mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
107
snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
110
static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
111
unsigned int val, int force)
113
unsigned int ngain, ogain;
116
snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
117
ngain = emu->i2c_capture_volume[val][0]; /* Left */
118
ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
119
if (force || ngain != ogain)
120
snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
121
ngain = emu->i2c_capture_volume[val][1]; /* Right */
122
ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
123
if (force || ngain != ogain)
124
snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
126
snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
127
emu->i2c_capture_source = val;
130
static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
134
if (emu->capture_mic_line_in) {
135
/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
136
tmp = inl(emu->port+GPIO) & ~0x400;
138
outl(tmp, emu->port+GPIO);
139
/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
141
/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
142
tmp = inl(emu->port+GPIO) & ~0x400;
143
outl(tmp, emu->port+GPIO);
144
/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
148
static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
150
snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
155
static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
156
static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
158
#define snd_ca0106_shared_spdif_info snd_ctl_boolean_mono_info
160
static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
161
struct snd_ctl_elem_value *ucontrol)
163
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
165
ucontrol->value.integer.value[0] = emu->spdif_enable;
169
static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
170
struct snd_ctl_elem_value *ucontrol)
172
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
176
val = !!ucontrol->value.integer.value[0];
177
change = (emu->spdif_enable != val);
179
emu->spdif_enable = val;
180
ca0106_spdif_enable(emu);
185
static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
186
struct snd_ctl_elem_info *uinfo)
188
static char *texts[6] = {
189
"IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
192
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
194
uinfo->value.enumerated.items = 6;
195
if (uinfo->value.enumerated.item > 5)
196
uinfo->value.enumerated.item = 5;
197
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
201
static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
202
struct snd_ctl_elem_value *ucontrol)
204
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
206
ucontrol->value.enumerated.item[0] = emu->capture_source;
210
static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
211
struct snd_ctl_elem_value *ucontrol)
213
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
217
val = ucontrol->value.enumerated.item[0] ;
220
change = (emu->capture_source != val);
222
emu->capture_source = val;
223
ca0106_set_capture_source(emu);
228
static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
229
struct snd_ctl_elem_info *uinfo)
231
static char *texts[6] = {
232
"Phone", "Mic", "Line in", "Aux"
235
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
237
uinfo->value.enumerated.items = 4;
238
if (uinfo->value.enumerated.item > 3)
239
uinfo->value.enumerated.item = 3;
240
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
244
static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
245
struct snd_ctl_elem_value *ucontrol)
247
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
249
ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
253
static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
254
struct snd_ctl_elem_value *ucontrol)
256
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
257
unsigned int source_id;
259
/* If the capture source has changed,
260
* update the capture volume from the cached value
261
* for the particular source.
263
source_id = ucontrol->value.enumerated.item[0] ;
266
change = (emu->i2c_capture_source != source_id);
268
ca0106_set_i2c_capture_source(emu, source_id, 0);
273
static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
274
struct snd_ctl_elem_info *uinfo)
276
static char *texts[2] = { "Side out", "Line in" };
278
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
280
uinfo->value.enumerated.items = 2;
281
if (uinfo->value.enumerated.item > 1)
282
uinfo->value.enumerated.item = 1;
283
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
287
static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
288
struct snd_ctl_elem_info *uinfo)
290
static char *texts[2] = { "Line in", "Mic in" };
292
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
294
uinfo->value.enumerated.items = 2;
295
if (uinfo->value.enumerated.item > 1)
296
uinfo->value.enumerated.item = 1;
297
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
301
static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
302
struct snd_ctl_elem_value *ucontrol)
304
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
306
ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
310
static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
311
struct snd_ctl_elem_value *ucontrol)
313
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
317
val = ucontrol->value.enumerated.item[0] ;
320
change = (emu->capture_mic_line_in != val);
322
emu->capture_mic_line_in = val;
323
ca0106_set_capture_mic_line_in(emu);
328
static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
330
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
331
.name = "Shared Mic/Line in Capture Switch",
332
.info = snd_ca0106_capture_mic_line_in_info,
333
.get = snd_ca0106_capture_mic_line_in_get,
334
.put = snd_ca0106_capture_mic_line_in_put
337
static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
339
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
340
.name = "Shared Line in/Side out Capture Switch",
341
.info = snd_ca0106_capture_line_in_side_out_info,
342
.get = snd_ca0106_capture_mic_line_in_get,
343
.put = snd_ca0106_capture_mic_line_in_put
347
static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
348
struct snd_ctl_elem_info *uinfo)
350
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
355
static void decode_spdif_bits(unsigned char *status, unsigned int bits)
357
status[0] = (bits >> 0) & 0xff;
358
status[1] = (bits >> 8) & 0xff;
359
status[2] = (bits >> 16) & 0xff;
360
status[3] = (bits >> 24) & 0xff;
363
static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
364
struct snd_ctl_elem_value *ucontrol)
366
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
367
unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
369
decode_spdif_bits(ucontrol->value.iec958.status,
370
emu->spdif_bits[idx]);
374
static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
375
struct snd_ctl_elem_value *ucontrol)
377
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
378
unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
380
decode_spdif_bits(ucontrol->value.iec958.status,
381
emu->spdif_str_bits[idx]);
385
static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
386
struct snd_ctl_elem_value *ucontrol)
388
ucontrol->value.iec958.status[0] = 0xff;
389
ucontrol->value.iec958.status[1] = 0xff;
390
ucontrol->value.iec958.status[2] = 0xff;
391
ucontrol->value.iec958.status[3] = 0xff;
395
static unsigned int encode_spdif_bits(unsigned char *status)
397
return ((unsigned int)status[0] << 0) |
398
((unsigned int)status[1] << 8) |
399
((unsigned int)status[2] << 16) |
400
((unsigned int)status[3] << 24);
403
static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
404
struct snd_ctl_elem_value *ucontrol)
406
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
407
unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
410
val = encode_spdif_bits(ucontrol->value.iec958.status);
411
if (val != emu->spdif_bits[idx]) {
412
emu->spdif_bits[idx] = val;
413
/* FIXME: this isn't safe, but needed to keep the compatibility
414
* with older alsa-lib config
416
emu->spdif_str_bits[idx] = val;
417
ca0106_set_spdif_bits(emu, idx);
423
static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
424
struct snd_ctl_elem_value *ucontrol)
426
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
427
unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
430
val = encode_spdif_bits(ucontrol->value.iec958.status);
431
if (val != emu->spdif_str_bits[idx]) {
432
emu->spdif_str_bits[idx] = val;
433
ca0106_set_spdif_bits(emu, idx);
439
static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
440
struct snd_ctl_elem_info *uinfo)
442
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
444
uinfo->value.integer.min = 0;
445
uinfo->value.integer.max = 255;
449
static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
450
struct snd_ctl_elem_value *ucontrol)
452
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
456
channel_id = (kcontrol->private_value >> 8) & 0xff;
457
reg = kcontrol->private_value & 0xff;
459
value = snd_ca0106_ptr_read(emu, reg, channel_id);
460
ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
461
ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
465
static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
466
struct snd_ctl_elem_value *ucontrol)
468
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
469
unsigned int oval, nval;
472
channel_id = (kcontrol->private_value >> 8) & 0xff;
473
reg = kcontrol->private_value & 0xff;
475
oval = snd_ca0106_ptr_read(emu, reg, channel_id);
476
nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
477
((0xff - ucontrol->value.integer.value[1]) << 16);
478
nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
479
((0xff - ucontrol->value.integer.value[1]) );
482
snd_ca0106_ptr_write(emu, reg, channel_id, nval);
486
static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
487
struct snd_ctl_elem_info *uinfo)
489
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
491
uinfo->value.integer.min = 0;
492
uinfo->value.integer.max = 255;
496
static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
497
struct snd_ctl_elem_value *ucontrol)
499
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
502
source_id = kcontrol->private_value;
504
ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
505
ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
509
static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
510
struct snd_ctl_elem_value *ucontrol)
512
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
518
source_id = kcontrol->private_value;
519
ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
520
ngain = ucontrol->value.integer.value[0];
523
if (ogain != ngain) {
524
if (emu->i2c_capture_source == source_id)
525
snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
526
emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
529
ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
530
ngain = ucontrol->value.integer.value[1];
533
if (ogain != ngain) {
534
if (emu->i2c_capture_source == source_id)
535
snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
536
emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
543
#define spi_mute_info snd_ctl_boolean_mono_info
545
static int spi_mute_get(struct snd_kcontrol *kcontrol,
546
struct snd_ctl_elem_value *ucontrol)
548
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
549
unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
550
unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
552
ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
556
static int spi_mute_put(struct snd_kcontrol *kcontrol,
557
struct snd_ctl_elem_value *ucontrol)
559
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
560
unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
561
unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
564
ret = emu->spi_dac_reg[reg] & bit;
565
if (ucontrol->value.integer.value[0]) {
566
if (!ret) /* bit already cleared, do nothing */
568
emu->spi_dac_reg[reg] &= ~bit;
570
if (ret) /* bit already set, do nothing */
572
emu->spi_dac_reg[reg] |= bit;
575
ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
576
return ret ? -EINVAL : 1;
579
#define CA_VOLUME(xname,chid,reg) \
581
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
582
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
583
SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
584
.info = snd_ca0106_volume_info, \
585
.get = snd_ca0106_volume_get, \
586
.put = snd_ca0106_volume_put, \
587
.tlv = { .p = snd_ca0106_db_scale1 }, \
588
.private_value = ((chid) << 8) | (reg) \
591
static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
592
CA_VOLUME("Analog Front Playback Volume",
593
CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
594
CA_VOLUME("Analog Rear Playback Volume",
595
CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
596
CA_VOLUME("Analog Center/LFE Playback Volume",
597
CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
598
CA_VOLUME("Analog Side Playback Volume",
599
CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
601
CA_VOLUME("IEC958 Front Playback Volume",
602
CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
603
CA_VOLUME("IEC958 Rear Playback Volume",
604
CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
605
CA_VOLUME("IEC958 Center/LFE Playback Volume",
606
CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
607
CA_VOLUME("IEC958 Unknown Playback Volume",
608
CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
610
CA_VOLUME("CAPTURE feedback Playback Volume",
614
.access = SNDRV_CTL_ELEM_ACCESS_READ,
615
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
616
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
618
.info = snd_ca0106_spdif_info,
619
.get = snd_ca0106_spdif_get_mask
622
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
623
.name = "IEC958 Playback Switch",
624
.info = snd_ca0106_shared_spdif_info,
625
.get = snd_ca0106_shared_spdif_get,
626
.put = snd_ca0106_shared_spdif_put
629
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
630
.name = "Digital Source Capture Enum",
631
.info = snd_ca0106_capture_source_info,
632
.get = snd_ca0106_capture_source_get,
633
.put = snd_ca0106_capture_source_put
636
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
637
.name = "Analog Source Capture Enum",
638
.info = snd_ca0106_i2c_capture_source_info,
639
.get = snd_ca0106_i2c_capture_source_get,
640
.put = snd_ca0106_i2c_capture_source_put
643
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
644
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
646
.info = snd_ca0106_spdif_info,
647
.get = snd_ca0106_spdif_get_default,
648
.put = snd_ca0106_spdif_put_default
651
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
652
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
654
.info = snd_ca0106_spdif_info,
655
.get = snd_ca0106_spdif_get_stream,
656
.put = snd_ca0106_spdif_put_stream
660
#define I2C_VOLUME(xname,chid) \
662
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
663
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
664
SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
665
.info = snd_ca0106_i2c_volume_info, \
666
.get = snd_ca0106_i2c_volume_get, \
667
.put = snd_ca0106_i2c_volume_put, \
668
.tlv = { .p = snd_ca0106_db_scale2 }, \
669
.private_value = chid \
672
static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = {
673
I2C_VOLUME("Phone Capture Volume", 0),
674
I2C_VOLUME("Mic Capture Volume", 1),
675
I2C_VOLUME("Line in Capture Volume", 2),
676
I2C_VOLUME("Aux Capture Volume", 3),
679
static const int spi_dmute_reg[] = {
686
static const int spi_dmute_bit[] = {
694
static struct snd_kcontrol_new __devinit
695
snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details,
698
struct snd_kcontrol_new spi_switch = {0};
702
spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
703
spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
704
spi_switch.info = spi_mute_info;
705
spi_switch.get = spi_mute_get;
706
spi_switch.put = spi_mute_put;
708
switch (channel_id) {
709
case PCM_FRONT_CHANNEL:
710
spi_switch.name = "Analog Front Playback Switch";
711
dac_id = (details->spi_dac & 0xf000) >> (4 * 3);
713
case PCM_REAR_CHANNEL:
714
spi_switch.name = "Analog Rear Playback Switch";
715
dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
717
case PCM_CENTER_LFE_CHANNEL:
718
spi_switch.name = "Analog Center/LFE Playback Switch";
719
dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
721
case PCM_UNKNOWN_CHANNEL:
722
spi_switch.name = "Analog Side Playback Switch";
723
dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
727
spi_switch.name = NULL;
730
reg = spi_dmute_reg[dac_id];
731
bit = spi_dmute_bit[dac_id];
733
spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
738
static int __devinit remove_ctl(struct snd_card *card, const char *name)
740
struct snd_ctl_elem_id id;
741
memset(&id, 0, sizeof(id));
742
strcpy(id.name, name);
743
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
744
return snd_ctl_remove_id(card, &id);
747
static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, const char *name)
749
struct snd_ctl_elem_id sid;
750
memset(&sid, 0, sizeof(sid));
751
/* FIXME: strcpy is bad. */
752
strcpy(sid.name, name);
753
sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
754
return snd_ctl_find_id(card, &sid);
757
static int __devinit rename_ctl(struct snd_card *card, const char *src, const char *dst)
759
struct snd_kcontrol *kctl = ctl_find(card, src);
761
strcpy(kctl->id.name, dst);
767
#define ADD_CTLS(emu, ctls) \
770
for (i = 0; i < ARRAY_SIZE(ctls); i++) { \
771
_err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
778
DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
780
static char *slave_vols[] __devinitdata = {
781
"Analog Front Playback Volume",
782
"Analog Rear Playback Volume",
783
"Analog Center/LFE Playback Volume",
784
"Analog Side Playback Volume",
785
"IEC958 Front Playback Volume",
786
"IEC958 Rear Playback Volume",
787
"IEC958 Center/LFE Playback Volume",
788
"IEC958 Unknown Playback Volume",
789
"CAPTURE feedback Playback Volume",
793
static char *slave_sws[] __devinitdata = {
794
"Analog Front Playback Switch",
795
"Analog Rear Playback Switch",
796
"Analog Center/LFE Playback Switch",
797
"Analog Side Playback Switch",
798
"IEC958 Playback Switch",
802
static void __devinit add_slaves(struct snd_card *card,
803
struct snd_kcontrol *master, char **list)
805
for (; *list; list++) {
806
struct snd_kcontrol *slave = ctl_find(card, *list);
808
snd_ctl_add_slave(master, slave);
812
int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
815
struct snd_card *card = emu->card;
817
struct snd_kcontrol *vmaster;
818
static char *ca0106_remove_ctls[] = {
819
"Master Mono Playback Switch",
820
"Master Mono Playback Volume",
821
"3D Control - Switch",
822
"3D Control Sigmatel - Depth",
823
"PCM Playback Switch",
824
"PCM Playback Volume",
825
"CD Playback Switch",
826
"CD Playback Volume",
827
"Phone Playback Switch",
828
"Phone Playback Volume",
829
"Video Playback Switch",
830
"Video Playback Volume",
831
"Beep Playback Switch",
832
"Beep Playback Volume",
833
"Mono Output Select",
837
"External Amplifier",
838
"Sigmatel 4-Speaker Stereo Playback Switch",
839
"Surround Phase Inversion Playback Switch",
842
static char *ca0106_rename_ctls[] = {
843
"Master Playback Switch", "Capture Switch",
844
"Master Playback Volume", "Capture Volume",
845
"Line Playback Switch", "AC97 Line Capture Switch",
846
"Line Playback Volume", "AC97 Line Capture Volume",
847
"Aux Playback Switch", "AC97 Aux Capture Switch",
848
"Aux Playback Volume", "AC97 Aux Capture Volume",
849
"Mic Playback Switch", "AC97 Mic Capture Switch",
850
"Mic Playback Volume", "AC97 Mic Capture Volume",
851
"Mic Select", "AC97 Mic Select",
852
"Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
856
for (c = ca0106_remove_ctls; *c; c++)
857
remove_ctl(card, *c);
858
for (c = ca0106_rename_ctls; *c; c += 2)
859
rename_ctl(card, c[0], c[1]);
862
ADD_CTLS(emu, snd_ca0106_volume_ctls);
863
if (emu->details->i2c_adc == 1) {
864
ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
865
if (emu->details->gpio_type == 1)
866
err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
867
else /* gpio_type == 2 */
868
err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
872
if (emu->details->spi_dac) {
875
struct snd_kcontrol_new ctl;
876
ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
879
err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
885
/* Create virtual master controls */
886
vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
887
snd_ca0106_master_db_scale);
890
err = snd_ctl_add(card, vmaster);
893
add_slaves(card, vmaster, slave_vols);
895
if (emu->details->spi_dac) {
896
vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
900
err = snd_ctl_add(card, vmaster);
903
add_slaves(card, vmaster, slave_sws);
906
strcpy(card->mixername, "CA0106");
911
struct ca0106_vol_tbl {
912
unsigned int channel_id;
916
static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
917
{ CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
918
{ CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
919
{ CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
920
{ CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
921
{ CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
922
{ CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
923
{ CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
924
{ CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
925
{ 1, CAPTURE_CONTROL },
928
void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
933
for (i = 0; i < NUM_SAVED_VOLUMES; i++)
935
snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
936
saved_volumes[i].channel_id);
939
void snd_ca0106_mixer_resume(struct snd_ca0106 *chip)
943
for (i = 0; i < NUM_SAVED_VOLUMES; i++)
944
snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
945
saved_volumes[i].channel_id,
948
ca0106_spdif_enable(chip);
949
ca0106_set_capture_source(chip);
950
ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
951
for (i = 0; i < 4; i++)
952
ca0106_set_spdif_bits(chip, i);
953
if (chip->details->i2c_adc)
954
ca0106_set_capture_mic_line_in(chip);
956
#endif /* CONFIG_PM */