1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
4 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
7 * FEATURES currently supported:
8 * See ca0106_main.c for features.
11 * Support interrupts per period.
12 * Removed noise from Center/LFE channel when in Analog mode.
13 * Rename and remove mixer controls.
15 * Use separate card based DMA buffer for periods table list.
17 * Change remove and rename ctrls into lists.
19 * Try to fix capture sources.
22 * Enable S32_LE format support.
24 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
26 * Add Model name recognition.
28 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
29 * Remove redundent "voice" handling.
31 * Single trigger call for multi channels.
33 * Set limits based on what the sound card hardware can do.
34 * playback periods_min=2, periods_max=8
35 * capture hw constraints require period_size = n * 64 bytes.
36 * playback hw constraints require period_size = n * 64 bytes.
38 * Separated ca0106.c into separate functional .c files.
40 * Modified Copyright message.
42 * Implement Mic and Line in Capture.
44 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
46 * This code was initially based on code from ALSA's emu10k1x.c which is:
47 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
49 #include <linux/delay.h>
50 #include <linux/init.h>
51 #include <linux/interrupt.h>
52 #include <linux/moduleparam.h>
53 #include <sound/core.h>
54 #include <sound/initval.h>
55 #include <sound/pcm.h>
56 #include <sound/ac97_codec.h>
57 #include <sound/info.h>
58 #include <sound/tlv.h>
63 static void ca0106_spdif_enable(struct snd_ca0106
*emu
)
67 if (emu
->spdif_enable
) {
69 snd_ca0106_ptr_write(emu
, SPDIF_SELECT1
, 0, 0xf);
70 snd_ca0106_ptr_write(emu
, SPDIF_SELECT2
, 0, 0x0b000000);
71 val
= snd_ca0106_ptr_read(emu
, CAPTURE_CONTROL
, 0) & ~0x1000;
72 snd_ca0106_ptr_write(emu
, CAPTURE_CONTROL
, 0, val
);
73 val
= inl(emu
->port
+ GPIO
) & ~0x101;
74 outl(val
, emu
->port
+ GPIO
);
78 snd_ca0106_ptr_write(emu
, SPDIF_SELECT1
, 0, 0xf);
79 snd_ca0106_ptr_write(emu
, SPDIF_SELECT2
, 0, 0x000f0000);
80 val
= snd_ca0106_ptr_read(emu
, CAPTURE_CONTROL
, 0) | 0x1000;
81 snd_ca0106_ptr_write(emu
, CAPTURE_CONTROL
, 0, val
);
82 val
= inl(emu
->port
+ GPIO
) | 0x101;
83 outl(val
, emu
->port
+ GPIO
);
87 static void ca0106_set_capture_source(struct snd_ca0106
*emu
)
89 unsigned int val
= emu
->capture_source
;
90 unsigned int source
, mask
;
91 source
= (val
<< 28) | (val
<< 24) | (val
<< 20) | (val
<< 16);
92 mask
= snd_ca0106_ptr_read(emu
, CAPTURE_SOURCE
, 0) & 0xffff;
93 snd_ca0106_ptr_write(emu
, CAPTURE_SOURCE
, 0, source
| mask
);
96 static void ca0106_set_i2c_capture_source(struct snd_ca0106
*emu
,
97 unsigned int val
, int force
)
99 unsigned int ngain
, ogain
;
102 snd_ca0106_i2c_write(emu
, ADC_MUX
, 0); /* Mute input */
103 ngain
= emu
->i2c_capture_volume
[val
][0]; /* Left */
104 ogain
= emu
->i2c_capture_volume
[emu
->i2c_capture_source
][0]; /* Left */
105 if (force
|| ngain
!= ogain
)
106 snd_ca0106_i2c_write(emu
, ADC_ATTEN_ADCL
, ngain
& 0xff);
107 ngain
= emu
->i2c_capture_volume
[val
][1]; /* Right */
108 ogain
= emu
->i2c_capture_volume
[emu
->i2c_capture_source
][1]; /* Right */
109 if (force
|| ngain
!= ogain
)
110 snd_ca0106_i2c_write(emu
, ADC_ATTEN_ADCR
, ngain
& 0xff);
112 snd_ca0106_i2c_write(emu
, ADC_MUX
, source
); /* Set source */
113 emu
->i2c_capture_source
= val
;
116 static void ca0106_set_capture_mic_line_in(struct snd_ca0106
*emu
)
120 if (emu
->capture_mic_line_in
) {
121 /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
122 tmp
= inl(emu
->port
+GPIO
) & ~0x400;
124 outl(tmp
, emu
->port
+GPIO
);
125 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
127 /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
128 tmp
= inl(emu
->port
+GPIO
) & ~0x400;
129 outl(tmp
, emu
->port
+GPIO
);
130 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
134 static void ca0106_set_spdif_bits(struct snd_ca0106
*emu
, int idx
)
136 snd_ca0106_ptr_write(emu
, SPCS0
+ idx
, 0, emu
->spdif_str_bits
[idx
]);
141 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1
, -5175, 25, 1);
142 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2
, -10350, 50, 1);
144 #define snd_ca0106_shared_spdif_info snd_ctl_boolean_mono_info
146 static int snd_ca0106_shared_spdif_get(struct snd_kcontrol
*kcontrol
,
147 struct snd_ctl_elem_value
*ucontrol
)
149 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
151 ucontrol
->value
.integer
.value
[0] = emu
->spdif_enable
;
155 static int snd_ca0106_shared_spdif_put(struct snd_kcontrol
*kcontrol
,
156 struct snd_ctl_elem_value
*ucontrol
)
158 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
162 val
= !!ucontrol
->value
.integer
.value
[0];
163 change
= (emu
->spdif_enable
!= val
);
165 emu
->spdif_enable
= val
;
166 ca0106_spdif_enable(emu
);
171 static int snd_ca0106_capture_source_info(struct snd_kcontrol
*kcontrol
,
172 struct snd_ctl_elem_info
*uinfo
)
174 static const char * const texts
[6] = {
175 "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
178 return snd_ctl_enum_info(uinfo
, 1, 6, texts
);
181 static int snd_ca0106_capture_source_get(struct snd_kcontrol
*kcontrol
,
182 struct snd_ctl_elem_value
*ucontrol
)
184 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
186 ucontrol
->value
.enumerated
.item
[0] = emu
->capture_source
;
190 static int snd_ca0106_capture_source_put(struct snd_kcontrol
*kcontrol
,
191 struct snd_ctl_elem_value
*ucontrol
)
193 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
197 val
= ucontrol
->value
.enumerated
.item
[0] ;
200 change
= (emu
->capture_source
!= val
);
202 emu
->capture_source
= val
;
203 ca0106_set_capture_source(emu
);
208 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol
*kcontrol
,
209 struct snd_ctl_elem_info
*uinfo
)
211 static const char * const texts
[4] = {
212 "Phone", "Mic", "Line in", "Aux"
215 return snd_ctl_enum_info(uinfo
, 1, 4, texts
);
218 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol
*kcontrol
,
219 struct snd_ctl_elem_value
*ucontrol
)
221 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
223 ucontrol
->value
.enumerated
.item
[0] = emu
->i2c_capture_source
;
227 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol
*kcontrol
,
228 struct snd_ctl_elem_value
*ucontrol
)
230 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
231 unsigned int source_id
;
233 /* If the capture source has changed,
234 * update the capture volume from the cached value
235 * for the particular source.
237 source_id
= ucontrol
->value
.enumerated
.item
[0] ;
240 change
= (emu
->i2c_capture_source
!= source_id
);
242 ca0106_set_i2c_capture_source(emu
, source_id
, 0);
247 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol
*kcontrol
,
248 struct snd_ctl_elem_info
*uinfo
)
250 static const char * const texts
[2] = { "Side out", "Line in" };
252 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
255 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol
*kcontrol
,
256 struct snd_ctl_elem_info
*uinfo
)
258 static const char * const texts
[2] = { "Line in", "Mic in" };
260 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
263 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol
*kcontrol
,
264 struct snd_ctl_elem_value
*ucontrol
)
266 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
268 ucontrol
->value
.enumerated
.item
[0] = emu
->capture_mic_line_in
;
272 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol
*kcontrol
,
273 struct snd_ctl_elem_value
*ucontrol
)
275 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
279 val
= ucontrol
->value
.enumerated
.item
[0] ;
282 change
= (emu
->capture_mic_line_in
!= val
);
284 emu
->capture_mic_line_in
= val
;
285 ca0106_set_capture_mic_line_in(emu
);
290 static const struct snd_kcontrol_new snd_ca0106_capture_mic_line_in
=
292 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
293 .name
= "Shared Mic/Line in Capture Switch",
294 .info
= snd_ca0106_capture_mic_line_in_info
,
295 .get
= snd_ca0106_capture_mic_line_in_get
,
296 .put
= snd_ca0106_capture_mic_line_in_put
299 static const struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out
=
301 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
302 .name
= "Shared Line in/Side out Capture Switch",
303 .info
= snd_ca0106_capture_line_in_side_out_info
,
304 .get
= snd_ca0106_capture_mic_line_in_get
,
305 .put
= snd_ca0106_capture_mic_line_in_put
309 static int snd_ca0106_spdif_info(struct snd_kcontrol
*kcontrol
,
310 struct snd_ctl_elem_info
*uinfo
)
312 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
317 static void decode_spdif_bits(unsigned char *status
, unsigned int bits
)
319 status
[0] = (bits
>> 0) & 0xff;
320 status
[1] = (bits
>> 8) & 0xff;
321 status
[2] = (bits
>> 16) & 0xff;
322 status
[3] = (bits
>> 24) & 0xff;
325 static int snd_ca0106_spdif_get_default(struct snd_kcontrol
*kcontrol
,
326 struct snd_ctl_elem_value
*ucontrol
)
328 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
329 unsigned int idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
331 decode_spdif_bits(ucontrol
->value
.iec958
.status
,
332 emu
->spdif_bits
[idx
]);
336 static int snd_ca0106_spdif_get_stream(struct snd_kcontrol
*kcontrol
,
337 struct snd_ctl_elem_value
*ucontrol
)
339 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
340 unsigned int idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
342 decode_spdif_bits(ucontrol
->value
.iec958
.status
,
343 emu
->spdif_str_bits
[idx
]);
347 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol
*kcontrol
,
348 struct snd_ctl_elem_value
*ucontrol
)
350 ucontrol
->value
.iec958
.status
[0] = 0xff;
351 ucontrol
->value
.iec958
.status
[1] = 0xff;
352 ucontrol
->value
.iec958
.status
[2] = 0xff;
353 ucontrol
->value
.iec958
.status
[3] = 0xff;
357 static unsigned int encode_spdif_bits(unsigned char *status
)
359 return ((unsigned int)status
[0] << 0) |
360 ((unsigned int)status
[1] << 8) |
361 ((unsigned int)status
[2] << 16) |
362 ((unsigned int)status
[3] << 24);
365 static int snd_ca0106_spdif_put_default(struct snd_kcontrol
*kcontrol
,
366 struct snd_ctl_elem_value
*ucontrol
)
368 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
369 unsigned int idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
372 val
= encode_spdif_bits(ucontrol
->value
.iec958
.status
);
373 if (val
!= emu
->spdif_bits
[idx
]) {
374 emu
->spdif_bits
[idx
] = val
;
375 /* FIXME: this isn't safe, but needed to keep the compatibility
376 * with older alsa-lib config
378 emu
->spdif_str_bits
[idx
] = val
;
379 ca0106_set_spdif_bits(emu
, idx
);
385 static int snd_ca0106_spdif_put_stream(struct snd_kcontrol
*kcontrol
,
386 struct snd_ctl_elem_value
*ucontrol
)
388 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
389 unsigned int idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
392 val
= encode_spdif_bits(ucontrol
->value
.iec958
.status
);
393 if (val
!= emu
->spdif_str_bits
[idx
]) {
394 emu
->spdif_str_bits
[idx
] = val
;
395 ca0106_set_spdif_bits(emu
, idx
);
401 static int snd_ca0106_volume_info(struct snd_kcontrol
*kcontrol
,
402 struct snd_ctl_elem_info
*uinfo
)
404 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
406 uinfo
->value
.integer
.min
= 0;
407 uinfo
->value
.integer
.max
= 255;
411 static int snd_ca0106_volume_get(struct snd_kcontrol
*kcontrol
,
412 struct snd_ctl_elem_value
*ucontrol
)
414 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
418 channel_id
= (kcontrol
->private_value
>> 8) & 0xff;
419 reg
= kcontrol
->private_value
& 0xff;
421 value
= snd_ca0106_ptr_read(emu
, reg
, channel_id
);
422 ucontrol
->value
.integer
.value
[0] = 0xff - ((value
>> 24) & 0xff); /* Left */
423 ucontrol
->value
.integer
.value
[1] = 0xff - ((value
>> 16) & 0xff); /* Right */
427 static int snd_ca0106_volume_put(struct snd_kcontrol
*kcontrol
,
428 struct snd_ctl_elem_value
*ucontrol
)
430 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
431 unsigned int oval
, nval
;
434 channel_id
= (kcontrol
->private_value
>> 8) & 0xff;
435 reg
= kcontrol
->private_value
& 0xff;
437 oval
= snd_ca0106_ptr_read(emu
, reg
, channel_id
);
438 nval
= ((0xff - ucontrol
->value
.integer
.value
[0]) << 24) |
439 ((0xff - ucontrol
->value
.integer
.value
[1]) << 16);
440 nval
|= ((0xff - ucontrol
->value
.integer
.value
[0]) << 8) |
441 ((0xff - ucontrol
->value
.integer
.value
[1]) );
444 snd_ca0106_ptr_write(emu
, reg
, channel_id
, nval
);
448 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol
*kcontrol
,
449 struct snd_ctl_elem_info
*uinfo
)
451 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
453 uinfo
->value
.integer
.min
= 0;
454 uinfo
->value
.integer
.max
= 255;
458 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol
*kcontrol
,
459 struct snd_ctl_elem_value
*ucontrol
)
461 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
464 source_id
= kcontrol
->private_value
;
466 ucontrol
->value
.integer
.value
[0] = emu
->i2c_capture_volume
[source_id
][0];
467 ucontrol
->value
.integer
.value
[1] = emu
->i2c_capture_volume
[source_id
][1];
471 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol
*kcontrol
,
472 struct snd_ctl_elem_value
*ucontrol
)
474 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
480 source_id
= kcontrol
->private_value
;
481 ogain
= emu
->i2c_capture_volume
[source_id
][0]; /* Left */
482 ngain
= ucontrol
->value
.integer
.value
[0];
485 if (ogain
!= ngain
) {
486 if (emu
->i2c_capture_source
== source_id
)
487 snd_ca0106_i2c_write(emu
, ADC_ATTEN_ADCL
, ((ngain
) & 0xff) );
488 emu
->i2c_capture_volume
[source_id
][0] = ucontrol
->value
.integer
.value
[0];
491 ogain
= emu
->i2c_capture_volume
[source_id
][1]; /* Right */
492 ngain
= ucontrol
->value
.integer
.value
[1];
495 if (ogain
!= ngain
) {
496 if (emu
->i2c_capture_source
== source_id
)
497 snd_ca0106_i2c_write(emu
, ADC_ATTEN_ADCR
, ((ngain
) & 0xff));
498 emu
->i2c_capture_volume
[source_id
][1] = ucontrol
->value
.integer
.value
[1];
505 #define spi_mute_info snd_ctl_boolean_mono_info
507 static int spi_mute_get(struct snd_kcontrol
*kcontrol
,
508 struct snd_ctl_elem_value
*ucontrol
)
510 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
511 unsigned int reg
= kcontrol
->private_value
>> SPI_REG_SHIFT
;
512 unsigned int bit
= kcontrol
->private_value
& SPI_REG_MASK
;
514 ucontrol
->value
.integer
.value
[0] = !(emu
->spi_dac_reg
[reg
] & bit
);
518 static int spi_mute_put(struct snd_kcontrol
*kcontrol
,
519 struct snd_ctl_elem_value
*ucontrol
)
521 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
522 unsigned int reg
= kcontrol
->private_value
>> SPI_REG_SHIFT
;
523 unsigned int bit
= kcontrol
->private_value
& SPI_REG_MASK
;
526 ret
= emu
->spi_dac_reg
[reg
] & bit
;
527 if (ucontrol
->value
.integer
.value
[0]) {
528 if (!ret
) /* bit already cleared, do nothing */
530 emu
->spi_dac_reg
[reg
] &= ~bit
;
532 if (ret
) /* bit already set, do nothing */
534 emu
->spi_dac_reg
[reg
] |= bit
;
537 ret
= snd_ca0106_spi_write(emu
, emu
->spi_dac_reg
[reg
]);
538 return ret
? -EINVAL
: 1;
541 #define CA_VOLUME(xname,chid,reg) \
543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
544 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
545 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
546 .info = snd_ca0106_volume_info, \
547 .get = snd_ca0106_volume_get, \
548 .put = snd_ca0106_volume_put, \
549 .tlv = { .p = snd_ca0106_db_scale1 }, \
550 .private_value = ((chid) << 8) | (reg) \
553 static const struct snd_kcontrol_new snd_ca0106_volume_ctls
[] = {
554 CA_VOLUME("Analog Front Playback Volume",
555 CONTROL_FRONT_CHANNEL
, PLAYBACK_VOLUME2
),
556 CA_VOLUME("Analog Rear Playback Volume",
557 CONTROL_REAR_CHANNEL
, PLAYBACK_VOLUME2
),
558 CA_VOLUME("Analog Center/LFE Playback Volume",
559 CONTROL_CENTER_LFE_CHANNEL
, PLAYBACK_VOLUME2
),
560 CA_VOLUME("Analog Side Playback Volume",
561 CONTROL_UNKNOWN_CHANNEL
, PLAYBACK_VOLUME2
),
563 CA_VOLUME("IEC958 Front Playback Volume",
564 CONTROL_FRONT_CHANNEL
, PLAYBACK_VOLUME1
),
565 CA_VOLUME("IEC958 Rear Playback Volume",
566 CONTROL_REAR_CHANNEL
, PLAYBACK_VOLUME1
),
567 CA_VOLUME("IEC958 Center/LFE Playback Volume",
568 CONTROL_CENTER_LFE_CHANNEL
, PLAYBACK_VOLUME1
),
569 CA_VOLUME("IEC958 Unknown Playback Volume",
570 CONTROL_UNKNOWN_CHANNEL
, PLAYBACK_VOLUME1
),
572 CA_VOLUME("CAPTURE feedback Playback Volume",
576 .access
= SNDRV_CTL_ELEM_ACCESS_READ
,
577 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
578 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,MASK
),
580 .info
= snd_ca0106_spdif_info
,
581 .get
= snd_ca0106_spdif_get_mask
584 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
585 .name
= "IEC958 Playback Switch",
586 .info
= snd_ca0106_shared_spdif_info
,
587 .get
= snd_ca0106_shared_spdif_get
,
588 .put
= snd_ca0106_shared_spdif_put
591 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
592 .name
= "Digital Source Capture Enum",
593 .info
= snd_ca0106_capture_source_info
,
594 .get
= snd_ca0106_capture_source_get
,
595 .put
= snd_ca0106_capture_source_put
598 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
599 .name
= "Analog Source Capture Enum",
600 .info
= snd_ca0106_i2c_capture_source_info
,
601 .get
= snd_ca0106_i2c_capture_source_get
,
602 .put
= snd_ca0106_i2c_capture_source_put
605 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
606 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,DEFAULT
),
608 .info
= snd_ca0106_spdif_info
,
609 .get
= snd_ca0106_spdif_get_default
,
610 .put
= snd_ca0106_spdif_put_default
613 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
614 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,PCM_STREAM
),
616 .info
= snd_ca0106_spdif_info
,
617 .get
= snd_ca0106_spdif_get_stream
,
618 .put
= snd_ca0106_spdif_put_stream
622 #define I2C_VOLUME(xname,chid) \
624 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
625 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
626 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
627 .info = snd_ca0106_i2c_volume_info, \
628 .get = snd_ca0106_i2c_volume_get, \
629 .put = snd_ca0106_i2c_volume_put, \
630 .tlv = { .p = snd_ca0106_db_scale2 }, \
631 .private_value = chid \
634 static const struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls
[] = {
635 I2C_VOLUME("Phone Capture Volume", 0),
636 I2C_VOLUME("Mic Capture Volume", 1),
637 I2C_VOLUME("Line in Capture Volume", 2),
638 I2C_VOLUME("Aux Capture Volume", 3),
641 static const int spi_dmute_reg
[] = {
648 static const int spi_dmute_bit
[] = {
656 static struct snd_kcontrol_new
657 snd_ca0106_volume_spi_dac_ctl(const struct snd_ca0106_details
*details
,
660 struct snd_kcontrol_new spi_switch
= {0};
664 spi_switch
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
665 spi_switch
.access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
;
666 spi_switch
.info
= spi_mute_info
;
667 spi_switch
.get
= spi_mute_get
;
668 spi_switch
.put
= spi_mute_put
;
670 switch (channel_id
) {
671 case PCM_FRONT_CHANNEL
:
672 spi_switch
.name
= "Analog Front Playback Switch";
673 dac_id
= (details
->spi_dac
& 0xf000) >> (4 * 3);
675 case PCM_REAR_CHANNEL
:
676 spi_switch
.name
= "Analog Rear Playback Switch";
677 dac_id
= (details
->spi_dac
& 0x0f00) >> (4 * 2);
679 case PCM_CENTER_LFE_CHANNEL
:
680 spi_switch
.name
= "Analog Center/LFE Playback Switch";
681 dac_id
= (details
->spi_dac
& 0x00f0) >> (4 * 1);
683 case PCM_UNKNOWN_CHANNEL
:
684 spi_switch
.name
= "Analog Side Playback Switch";
685 dac_id
= (details
->spi_dac
& 0x000f) >> (4 * 0);
689 spi_switch
.name
= NULL
;
692 reg
= spi_dmute_reg
[dac_id
];
693 bit
= spi_dmute_bit
[dac_id
];
695 spi_switch
.private_value
= (reg
<< SPI_REG_SHIFT
) | bit
;
700 static int remove_ctl(struct snd_card
*card
, const char *name
)
702 struct snd_ctl_elem_id id
;
703 memset(&id
, 0, sizeof(id
));
704 strcpy(id
.name
, name
);
705 id
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
706 return snd_ctl_remove_id(card
, &id
);
709 static struct snd_kcontrol
*ctl_find(struct snd_card
*card
, const char *name
)
711 struct snd_ctl_elem_id sid
;
712 memset(&sid
, 0, sizeof(sid
));
713 /* FIXME: strcpy is bad. */
714 strcpy(sid
.name
, name
);
715 sid
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
716 return snd_ctl_find_id(card
, &sid
);
719 static int rename_ctl(struct snd_card
*card
, const char *src
, const char *dst
)
721 struct snd_kcontrol
*kctl
= ctl_find(card
, src
);
723 strcpy(kctl
->id
.name
, dst
);
729 #define ADD_CTLS(emu, ctls) \
732 for (i = 0; i < ARRAY_SIZE(ctls); i++) { \
733 _err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
740 DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale
, -6375, 25, 1);
742 static const char * const follower_vols
[] = {
743 "Analog Front Playback Volume",
744 "Analog Rear Playback Volume",
745 "Analog Center/LFE Playback Volume",
746 "Analog Side Playback Volume",
747 "IEC958 Front Playback Volume",
748 "IEC958 Rear Playback Volume",
749 "IEC958 Center/LFE Playback Volume",
750 "IEC958 Unknown Playback Volume",
751 "CAPTURE feedback Playback Volume",
755 static const char * const follower_sws
[] = {
756 "Analog Front Playback Switch",
757 "Analog Rear Playback Switch",
758 "Analog Center/LFE Playback Switch",
759 "Analog Side Playback Switch",
760 "IEC958 Playback Switch",
764 static void add_followers(struct snd_card
*card
,
765 struct snd_kcontrol
*master
, const char * const *list
)
767 for (; *list
; list
++) {
768 struct snd_kcontrol
*follower
= ctl_find(card
, *list
);
770 snd_ctl_add_follower(master
, follower
);
774 int snd_ca0106_mixer(struct snd_ca0106
*emu
)
777 struct snd_card
*card
= emu
->card
;
778 const char * const *c
;
779 struct snd_kcontrol
*vmaster
;
780 static const char * const ca0106_remove_ctls
[] = {
781 "Master Mono Playback Switch",
782 "Master Mono Playback Volume",
783 "3D Control - Switch",
784 "3D Control Sigmatel - Depth",
785 "PCM Playback Switch",
786 "PCM Playback Volume",
787 "CD Playback Switch",
788 "CD Playback Volume",
789 "Phone Playback Switch",
790 "Phone Playback Volume",
791 "Video Playback Switch",
792 "Video Playback Volume",
793 "Beep Playback Switch",
794 "Beep Playback Volume",
795 "Mono Output Select",
799 "External Amplifier",
800 "Sigmatel 4-Speaker Stereo Playback Switch",
801 "Surround Phase Inversion Playback Switch",
804 static const char * const ca0106_rename_ctls
[] = {
805 "Master Playback Switch", "Capture Switch",
806 "Master Playback Volume", "Capture Volume",
807 "Line Playback Switch", "AC97 Line Capture Switch",
808 "Line Playback Volume", "AC97 Line Capture Volume",
809 "Aux Playback Switch", "AC97 Aux Capture Switch",
810 "Aux Playback Volume", "AC97 Aux Capture Volume",
811 "Mic Playback Switch", "AC97 Mic Capture Switch",
812 "Mic Playback Volume", "AC97 Mic Capture Volume",
813 "Mic Select", "AC97 Mic Select",
814 "Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
818 for (c
= ca0106_remove_ctls
; *c
; c
++)
819 remove_ctl(card
, *c
);
820 for (c
= ca0106_rename_ctls
; *c
; c
+= 2)
821 rename_ctl(card
, c
[0], c
[1]);
824 ADD_CTLS(emu
, snd_ca0106_volume_ctls
);
825 if (emu
->details
->i2c_adc
== 1) {
826 ADD_CTLS(emu
, snd_ca0106_volume_i2c_adc_ctls
);
827 if (emu
->details
->gpio_type
== 1)
828 err
= snd_ctl_add(card
, snd_ctl_new1(&snd_ca0106_capture_mic_line_in
, emu
));
829 else /* gpio_type == 2 */
830 err
= snd_ctl_add(card
, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out
, emu
));
834 if (emu
->details
->spi_dac
) {
837 struct snd_kcontrol_new ctl
;
838 ctl
= snd_ca0106_volume_spi_dac_ctl(emu
->details
, i
);
841 err
= snd_ctl_add(card
, snd_ctl_new1(&ctl
, emu
));
847 /* Create virtual master controls */
848 vmaster
= snd_ctl_make_virtual_master("Master Playback Volume",
849 snd_ca0106_master_db_scale
);
852 err
= snd_ctl_add(card
, vmaster
);
855 add_followers(card
, vmaster
, follower_vols
);
857 if (emu
->details
->spi_dac
) {
858 vmaster
= snd_ctl_make_virtual_master("Master Playback Switch",
862 err
= snd_ctl_add(card
, vmaster
);
865 add_followers(card
, vmaster
, follower_sws
);
868 strcpy(card
->mixername
, "CA0106");
872 #ifdef CONFIG_PM_SLEEP
873 struct ca0106_vol_tbl
{
874 unsigned int channel_id
;
878 static const struct ca0106_vol_tbl saved_volumes
[NUM_SAVED_VOLUMES
] = {
879 { CONTROL_FRONT_CHANNEL
, PLAYBACK_VOLUME2
},
880 { CONTROL_REAR_CHANNEL
, PLAYBACK_VOLUME2
},
881 { CONTROL_CENTER_LFE_CHANNEL
, PLAYBACK_VOLUME2
},
882 { CONTROL_UNKNOWN_CHANNEL
, PLAYBACK_VOLUME2
},
883 { CONTROL_FRONT_CHANNEL
, PLAYBACK_VOLUME1
},
884 { CONTROL_REAR_CHANNEL
, PLAYBACK_VOLUME1
},
885 { CONTROL_CENTER_LFE_CHANNEL
, PLAYBACK_VOLUME1
},
886 { CONTROL_UNKNOWN_CHANNEL
, PLAYBACK_VOLUME1
},
887 { 1, CAPTURE_CONTROL
},
890 void snd_ca0106_mixer_suspend(struct snd_ca0106
*chip
)
895 for (i
= 0; i
< NUM_SAVED_VOLUMES
; i
++)
897 snd_ca0106_ptr_read(chip
, saved_volumes
[i
].reg
,
898 saved_volumes
[i
].channel_id
);
901 void snd_ca0106_mixer_resume(struct snd_ca0106
*chip
)
905 for (i
= 0; i
< NUM_SAVED_VOLUMES
; i
++)
906 snd_ca0106_ptr_write(chip
, saved_volumes
[i
].reg
,
907 saved_volumes
[i
].channel_id
,
910 ca0106_spdif_enable(chip
);
911 ca0106_set_capture_source(chip
);
912 ca0106_set_i2c_capture_source(chip
, chip
->i2c_capture_source
, 1);
913 for (i
= 0; i
< 4; i
++)
914 ca0106_set_spdif_bits(chip
, i
);
915 if (chip
->details
->i2c_adc
)
916 ca0106_set_capture_mic_line_in(chip
);
918 #endif /* CONFIG_PM_SLEEP */