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 const char * const texts
[6] = {
189 "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
192 return snd_ctl_enum_info(uinfo
, 1, 6, texts
);
195 static int snd_ca0106_capture_source_get(struct snd_kcontrol
*kcontrol
,
196 struct snd_ctl_elem_value
*ucontrol
)
198 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
200 ucontrol
->value
.enumerated
.item
[0] = emu
->capture_source
;
204 static int snd_ca0106_capture_source_put(struct snd_kcontrol
*kcontrol
,
205 struct snd_ctl_elem_value
*ucontrol
)
207 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
211 val
= ucontrol
->value
.enumerated
.item
[0] ;
214 change
= (emu
->capture_source
!= val
);
216 emu
->capture_source
= val
;
217 ca0106_set_capture_source(emu
);
222 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol
*kcontrol
,
223 struct snd_ctl_elem_info
*uinfo
)
225 static const char * const texts
[4] = {
226 "Phone", "Mic", "Line in", "Aux"
229 return snd_ctl_enum_info(uinfo
, 1, 4, texts
);
232 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol
*kcontrol
,
233 struct snd_ctl_elem_value
*ucontrol
)
235 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
237 ucontrol
->value
.enumerated
.item
[0] = emu
->i2c_capture_source
;
241 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol
*kcontrol
,
242 struct snd_ctl_elem_value
*ucontrol
)
244 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
245 unsigned int source_id
;
247 /* If the capture source has changed,
248 * update the capture volume from the cached value
249 * for the particular source.
251 source_id
= ucontrol
->value
.enumerated
.item
[0] ;
254 change
= (emu
->i2c_capture_source
!= source_id
);
256 ca0106_set_i2c_capture_source(emu
, source_id
, 0);
261 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol
*kcontrol
,
262 struct snd_ctl_elem_info
*uinfo
)
264 static const char * const texts
[2] = { "Side out", "Line in" };
266 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
269 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol
*kcontrol
,
270 struct snd_ctl_elem_info
*uinfo
)
272 static const char * const texts
[2] = { "Line in", "Mic in" };
274 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
277 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol
*kcontrol
,
278 struct snd_ctl_elem_value
*ucontrol
)
280 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
282 ucontrol
->value
.enumerated
.item
[0] = emu
->capture_mic_line_in
;
286 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol
*kcontrol
,
287 struct snd_ctl_elem_value
*ucontrol
)
289 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
293 val
= ucontrol
->value
.enumerated
.item
[0] ;
296 change
= (emu
->capture_mic_line_in
!= val
);
298 emu
->capture_mic_line_in
= val
;
299 ca0106_set_capture_mic_line_in(emu
);
304 static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in
=
306 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
307 .name
= "Shared Mic/Line in Capture Switch",
308 .info
= snd_ca0106_capture_mic_line_in_info
,
309 .get
= snd_ca0106_capture_mic_line_in_get
,
310 .put
= snd_ca0106_capture_mic_line_in_put
313 static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out
=
315 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
316 .name
= "Shared Line in/Side out Capture Switch",
317 .info
= snd_ca0106_capture_line_in_side_out_info
,
318 .get
= snd_ca0106_capture_mic_line_in_get
,
319 .put
= snd_ca0106_capture_mic_line_in_put
323 static int snd_ca0106_spdif_info(struct snd_kcontrol
*kcontrol
,
324 struct snd_ctl_elem_info
*uinfo
)
326 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
331 static void decode_spdif_bits(unsigned char *status
, unsigned int bits
)
333 status
[0] = (bits
>> 0) & 0xff;
334 status
[1] = (bits
>> 8) & 0xff;
335 status
[2] = (bits
>> 16) & 0xff;
336 status
[3] = (bits
>> 24) & 0xff;
339 static int snd_ca0106_spdif_get_default(struct snd_kcontrol
*kcontrol
,
340 struct snd_ctl_elem_value
*ucontrol
)
342 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
343 unsigned int idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
345 decode_spdif_bits(ucontrol
->value
.iec958
.status
,
346 emu
->spdif_bits
[idx
]);
350 static int snd_ca0106_spdif_get_stream(struct snd_kcontrol
*kcontrol
,
351 struct snd_ctl_elem_value
*ucontrol
)
353 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
354 unsigned int idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
356 decode_spdif_bits(ucontrol
->value
.iec958
.status
,
357 emu
->spdif_str_bits
[idx
]);
361 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol
*kcontrol
,
362 struct snd_ctl_elem_value
*ucontrol
)
364 ucontrol
->value
.iec958
.status
[0] = 0xff;
365 ucontrol
->value
.iec958
.status
[1] = 0xff;
366 ucontrol
->value
.iec958
.status
[2] = 0xff;
367 ucontrol
->value
.iec958
.status
[3] = 0xff;
371 static unsigned int encode_spdif_bits(unsigned char *status
)
373 return ((unsigned int)status
[0] << 0) |
374 ((unsigned int)status
[1] << 8) |
375 ((unsigned int)status
[2] << 16) |
376 ((unsigned int)status
[3] << 24);
379 static int snd_ca0106_spdif_put_default(struct snd_kcontrol
*kcontrol
,
380 struct snd_ctl_elem_value
*ucontrol
)
382 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
383 unsigned int idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
386 val
= encode_spdif_bits(ucontrol
->value
.iec958
.status
);
387 if (val
!= emu
->spdif_bits
[idx
]) {
388 emu
->spdif_bits
[idx
] = val
;
389 /* FIXME: this isn't safe, but needed to keep the compatibility
390 * with older alsa-lib config
392 emu
->spdif_str_bits
[idx
] = val
;
393 ca0106_set_spdif_bits(emu
, idx
);
399 static int snd_ca0106_spdif_put_stream(struct snd_kcontrol
*kcontrol
,
400 struct snd_ctl_elem_value
*ucontrol
)
402 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
403 unsigned int idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
406 val
= encode_spdif_bits(ucontrol
->value
.iec958
.status
);
407 if (val
!= emu
->spdif_str_bits
[idx
]) {
408 emu
->spdif_str_bits
[idx
] = val
;
409 ca0106_set_spdif_bits(emu
, idx
);
415 static int snd_ca0106_volume_info(struct snd_kcontrol
*kcontrol
,
416 struct snd_ctl_elem_info
*uinfo
)
418 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
420 uinfo
->value
.integer
.min
= 0;
421 uinfo
->value
.integer
.max
= 255;
425 static int snd_ca0106_volume_get(struct snd_kcontrol
*kcontrol
,
426 struct snd_ctl_elem_value
*ucontrol
)
428 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
432 channel_id
= (kcontrol
->private_value
>> 8) & 0xff;
433 reg
= kcontrol
->private_value
& 0xff;
435 value
= snd_ca0106_ptr_read(emu
, reg
, channel_id
);
436 ucontrol
->value
.integer
.value
[0] = 0xff - ((value
>> 24) & 0xff); /* Left */
437 ucontrol
->value
.integer
.value
[1] = 0xff - ((value
>> 16) & 0xff); /* Right */
441 static int snd_ca0106_volume_put(struct snd_kcontrol
*kcontrol
,
442 struct snd_ctl_elem_value
*ucontrol
)
444 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
445 unsigned int oval
, nval
;
448 channel_id
= (kcontrol
->private_value
>> 8) & 0xff;
449 reg
= kcontrol
->private_value
& 0xff;
451 oval
= snd_ca0106_ptr_read(emu
, reg
, channel_id
);
452 nval
= ((0xff - ucontrol
->value
.integer
.value
[0]) << 24) |
453 ((0xff - ucontrol
->value
.integer
.value
[1]) << 16);
454 nval
|= ((0xff - ucontrol
->value
.integer
.value
[0]) << 8) |
455 ((0xff - ucontrol
->value
.integer
.value
[1]) );
458 snd_ca0106_ptr_write(emu
, reg
, channel_id
, nval
);
462 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol
*kcontrol
,
463 struct snd_ctl_elem_info
*uinfo
)
465 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
467 uinfo
->value
.integer
.min
= 0;
468 uinfo
->value
.integer
.max
= 255;
472 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol
*kcontrol
,
473 struct snd_ctl_elem_value
*ucontrol
)
475 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
478 source_id
= kcontrol
->private_value
;
480 ucontrol
->value
.integer
.value
[0] = emu
->i2c_capture_volume
[source_id
][0];
481 ucontrol
->value
.integer
.value
[1] = emu
->i2c_capture_volume
[source_id
][1];
485 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol
*kcontrol
,
486 struct snd_ctl_elem_value
*ucontrol
)
488 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
494 source_id
= kcontrol
->private_value
;
495 ogain
= emu
->i2c_capture_volume
[source_id
][0]; /* Left */
496 ngain
= ucontrol
->value
.integer
.value
[0];
499 if (ogain
!= ngain
) {
500 if (emu
->i2c_capture_source
== source_id
)
501 snd_ca0106_i2c_write(emu
, ADC_ATTEN_ADCL
, ((ngain
) & 0xff) );
502 emu
->i2c_capture_volume
[source_id
][0] = ucontrol
->value
.integer
.value
[0];
505 ogain
= emu
->i2c_capture_volume
[source_id
][1]; /* Right */
506 ngain
= ucontrol
->value
.integer
.value
[1];
509 if (ogain
!= ngain
) {
510 if (emu
->i2c_capture_source
== source_id
)
511 snd_ca0106_i2c_write(emu
, ADC_ATTEN_ADCR
, ((ngain
) & 0xff));
512 emu
->i2c_capture_volume
[source_id
][1] = ucontrol
->value
.integer
.value
[1];
519 #define spi_mute_info snd_ctl_boolean_mono_info
521 static int spi_mute_get(struct snd_kcontrol
*kcontrol
,
522 struct snd_ctl_elem_value
*ucontrol
)
524 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
525 unsigned int reg
= kcontrol
->private_value
>> SPI_REG_SHIFT
;
526 unsigned int bit
= kcontrol
->private_value
& SPI_REG_MASK
;
528 ucontrol
->value
.integer
.value
[0] = !(emu
->spi_dac_reg
[reg
] & bit
);
532 static int spi_mute_put(struct snd_kcontrol
*kcontrol
,
533 struct snd_ctl_elem_value
*ucontrol
)
535 struct snd_ca0106
*emu
= snd_kcontrol_chip(kcontrol
);
536 unsigned int reg
= kcontrol
->private_value
>> SPI_REG_SHIFT
;
537 unsigned int bit
= kcontrol
->private_value
& SPI_REG_MASK
;
540 ret
= emu
->spi_dac_reg
[reg
] & bit
;
541 if (ucontrol
->value
.integer
.value
[0]) {
542 if (!ret
) /* bit already cleared, do nothing */
544 emu
->spi_dac_reg
[reg
] &= ~bit
;
546 if (ret
) /* bit already set, do nothing */
548 emu
->spi_dac_reg
[reg
] |= bit
;
551 ret
= snd_ca0106_spi_write(emu
, emu
->spi_dac_reg
[reg
]);
552 return ret
? -EINVAL
: 1;
555 #define CA_VOLUME(xname,chid,reg) \
557 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
558 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
559 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
560 .info = snd_ca0106_volume_info, \
561 .get = snd_ca0106_volume_get, \
562 .put = snd_ca0106_volume_put, \
563 .tlv = { .p = snd_ca0106_db_scale1 }, \
564 .private_value = ((chid) << 8) | (reg) \
567 static struct snd_kcontrol_new snd_ca0106_volume_ctls
[] = {
568 CA_VOLUME("Analog Front Playback Volume",
569 CONTROL_FRONT_CHANNEL
, PLAYBACK_VOLUME2
),
570 CA_VOLUME("Analog Rear Playback Volume",
571 CONTROL_REAR_CHANNEL
, PLAYBACK_VOLUME2
),
572 CA_VOLUME("Analog Center/LFE Playback Volume",
573 CONTROL_CENTER_LFE_CHANNEL
, PLAYBACK_VOLUME2
),
574 CA_VOLUME("Analog Side Playback Volume",
575 CONTROL_UNKNOWN_CHANNEL
, PLAYBACK_VOLUME2
),
577 CA_VOLUME("IEC958 Front Playback Volume",
578 CONTROL_FRONT_CHANNEL
, PLAYBACK_VOLUME1
),
579 CA_VOLUME("IEC958 Rear Playback Volume",
580 CONTROL_REAR_CHANNEL
, PLAYBACK_VOLUME1
),
581 CA_VOLUME("IEC958 Center/LFE Playback Volume",
582 CONTROL_CENTER_LFE_CHANNEL
, PLAYBACK_VOLUME1
),
583 CA_VOLUME("IEC958 Unknown Playback Volume",
584 CONTROL_UNKNOWN_CHANNEL
, PLAYBACK_VOLUME1
),
586 CA_VOLUME("CAPTURE feedback Playback Volume",
590 .access
= SNDRV_CTL_ELEM_ACCESS_READ
,
591 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
592 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,MASK
),
594 .info
= snd_ca0106_spdif_info
,
595 .get
= snd_ca0106_spdif_get_mask
598 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
599 .name
= "IEC958 Playback Switch",
600 .info
= snd_ca0106_shared_spdif_info
,
601 .get
= snd_ca0106_shared_spdif_get
,
602 .put
= snd_ca0106_shared_spdif_put
605 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
606 .name
= "Digital Source Capture Enum",
607 .info
= snd_ca0106_capture_source_info
,
608 .get
= snd_ca0106_capture_source_get
,
609 .put
= snd_ca0106_capture_source_put
612 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
613 .name
= "Analog Source Capture Enum",
614 .info
= snd_ca0106_i2c_capture_source_info
,
615 .get
= snd_ca0106_i2c_capture_source_get
,
616 .put
= snd_ca0106_i2c_capture_source_put
619 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
620 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,DEFAULT
),
622 .info
= snd_ca0106_spdif_info
,
623 .get
= snd_ca0106_spdif_get_default
,
624 .put
= snd_ca0106_spdif_put_default
627 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
628 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,PCM_STREAM
),
630 .info
= snd_ca0106_spdif_info
,
631 .get
= snd_ca0106_spdif_get_stream
,
632 .put
= snd_ca0106_spdif_put_stream
636 #define I2C_VOLUME(xname,chid) \
638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
639 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
640 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
641 .info = snd_ca0106_i2c_volume_info, \
642 .get = snd_ca0106_i2c_volume_get, \
643 .put = snd_ca0106_i2c_volume_put, \
644 .tlv = { .p = snd_ca0106_db_scale2 }, \
645 .private_value = chid \
648 static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls
[] = {
649 I2C_VOLUME("Phone Capture Volume", 0),
650 I2C_VOLUME("Mic Capture Volume", 1),
651 I2C_VOLUME("Line in Capture Volume", 2),
652 I2C_VOLUME("Aux Capture Volume", 3),
655 static const int spi_dmute_reg
[] = {
662 static const int spi_dmute_bit
[] = {
670 static struct snd_kcontrol_new
671 snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details
*details
,
674 struct snd_kcontrol_new spi_switch
= {0};
678 spi_switch
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
679 spi_switch
.access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
;
680 spi_switch
.info
= spi_mute_info
;
681 spi_switch
.get
= spi_mute_get
;
682 spi_switch
.put
= spi_mute_put
;
684 switch (channel_id
) {
685 case PCM_FRONT_CHANNEL
:
686 spi_switch
.name
= "Analog Front Playback Switch";
687 dac_id
= (details
->spi_dac
& 0xf000) >> (4 * 3);
689 case PCM_REAR_CHANNEL
:
690 spi_switch
.name
= "Analog Rear Playback Switch";
691 dac_id
= (details
->spi_dac
& 0x0f00) >> (4 * 2);
693 case PCM_CENTER_LFE_CHANNEL
:
694 spi_switch
.name
= "Analog Center/LFE Playback Switch";
695 dac_id
= (details
->spi_dac
& 0x00f0) >> (4 * 1);
697 case PCM_UNKNOWN_CHANNEL
:
698 spi_switch
.name
= "Analog Side Playback Switch";
699 dac_id
= (details
->spi_dac
& 0x000f) >> (4 * 0);
703 spi_switch
.name
= NULL
;
706 reg
= spi_dmute_reg
[dac_id
];
707 bit
= spi_dmute_bit
[dac_id
];
709 spi_switch
.private_value
= (reg
<< SPI_REG_SHIFT
) | bit
;
714 static int remove_ctl(struct snd_card
*card
, const char *name
)
716 struct snd_ctl_elem_id id
;
717 memset(&id
, 0, sizeof(id
));
718 strcpy(id
.name
, name
);
719 id
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
720 return snd_ctl_remove_id(card
, &id
);
723 static struct snd_kcontrol
*ctl_find(struct snd_card
*card
, const char *name
)
725 struct snd_ctl_elem_id sid
;
726 memset(&sid
, 0, sizeof(sid
));
727 /* FIXME: strcpy is bad. */
728 strcpy(sid
.name
, name
);
729 sid
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
730 return snd_ctl_find_id(card
, &sid
);
733 static int rename_ctl(struct snd_card
*card
, const char *src
, const char *dst
)
735 struct snd_kcontrol
*kctl
= ctl_find(card
, src
);
737 strcpy(kctl
->id
.name
, dst
);
743 #define ADD_CTLS(emu, ctls) \
746 for (i = 0; i < ARRAY_SIZE(ctls); i++) { \
747 _err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
754 DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale
, -6375, 25, 1);
756 static char *slave_vols
[] = {
757 "Analog Front Playback Volume",
758 "Analog Rear Playback Volume",
759 "Analog Center/LFE Playback Volume",
760 "Analog Side Playback Volume",
761 "IEC958 Front Playback Volume",
762 "IEC958 Rear Playback Volume",
763 "IEC958 Center/LFE Playback Volume",
764 "IEC958 Unknown Playback Volume",
765 "CAPTURE feedback Playback Volume",
769 static char *slave_sws
[] = {
770 "Analog Front Playback Switch",
771 "Analog Rear Playback Switch",
772 "Analog Center/LFE Playback Switch",
773 "Analog Side Playback Switch",
774 "IEC958 Playback Switch",
778 static void add_slaves(struct snd_card
*card
,
779 struct snd_kcontrol
*master
, char **list
)
781 for (; *list
; list
++) {
782 struct snd_kcontrol
*slave
= ctl_find(card
, *list
);
784 snd_ctl_add_slave(master
, slave
);
788 int snd_ca0106_mixer(struct snd_ca0106
*emu
)
791 struct snd_card
*card
= emu
->card
;
793 struct snd_kcontrol
*vmaster
;
794 static char *ca0106_remove_ctls
[] = {
795 "Master Mono Playback Switch",
796 "Master Mono Playback Volume",
797 "3D Control - Switch",
798 "3D Control Sigmatel - Depth",
799 "PCM Playback Switch",
800 "PCM Playback Volume",
801 "CD Playback Switch",
802 "CD Playback Volume",
803 "Phone Playback Switch",
804 "Phone Playback Volume",
805 "Video Playback Switch",
806 "Video Playback Volume",
807 "Beep Playback Switch",
808 "Beep Playback Volume",
809 "Mono Output Select",
813 "External Amplifier",
814 "Sigmatel 4-Speaker Stereo Playback Switch",
815 "Surround Phase Inversion Playback Switch",
818 static char *ca0106_rename_ctls
[] = {
819 "Master Playback Switch", "Capture Switch",
820 "Master Playback Volume", "Capture Volume",
821 "Line Playback Switch", "AC97 Line Capture Switch",
822 "Line Playback Volume", "AC97 Line Capture Volume",
823 "Aux Playback Switch", "AC97 Aux Capture Switch",
824 "Aux Playback Volume", "AC97 Aux Capture Volume",
825 "Mic Playback Switch", "AC97 Mic Capture Switch",
826 "Mic Playback Volume", "AC97 Mic Capture Volume",
827 "Mic Select", "AC97 Mic Select",
828 "Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
832 for (c
= ca0106_remove_ctls
; *c
; c
++)
833 remove_ctl(card
, *c
);
834 for (c
= ca0106_rename_ctls
; *c
; c
+= 2)
835 rename_ctl(card
, c
[0], c
[1]);
838 ADD_CTLS(emu
, snd_ca0106_volume_ctls
);
839 if (emu
->details
->i2c_adc
== 1) {
840 ADD_CTLS(emu
, snd_ca0106_volume_i2c_adc_ctls
);
841 if (emu
->details
->gpio_type
== 1)
842 err
= snd_ctl_add(card
, snd_ctl_new1(&snd_ca0106_capture_mic_line_in
, emu
));
843 else /* gpio_type == 2 */
844 err
= snd_ctl_add(card
, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out
, emu
));
848 if (emu
->details
->spi_dac
) {
851 struct snd_kcontrol_new ctl
;
852 ctl
= snd_ca0106_volume_spi_dac_ctl(emu
->details
, i
);
855 err
= snd_ctl_add(card
, snd_ctl_new1(&ctl
, emu
));
861 /* Create virtual master controls */
862 vmaster
= snd_ctl_make_virtual_master("Master Playback Volume",
863 snd_ca0106_master_db_scale
);
866 err
= snd_ctl_add(card
, vmaster
);
869 add_slaves(card
, vmaster
, slave_vols
);
871 if (emu
->details
->spi_dac
) {
872 vmaster
= snd_ctl_make_virtual_master("Master Playback Switch",
876 err
= snd_ctl_add(card
, vmaster
);
879 add_slaves(card
, vmaster
, slave_sws
);
882 strcpy(card
->mixername
, "CA0106");
886 #ifdef CONFIG_PM_SLEEP
887 struct ca0106_vol_tbl
{
888 unsigned int channel_id
;
892 static struct ca0106_vol_tbl saved_volumes
[NUM_SAVED_VOLUMES
] = {
893 { CONTROL_FRONT_CHANNEL
, PLAYBACK_VOLUME2
},
894 { CONTROL_REAR_CHANNEL
, PLAYBACK_VOLUME2
},
895 { CONTROL_CENTER_LFE_CHANNEL
, PLAYBACK_VOLUME2
},
896 { CONTROL_UNKNOWN_CHANNEL
, PLAYBACK_VOLUME2
},
897 { CONTROL_FRONT_CHANNEL
, PLAYBACK_VOLUME1
},
898 { CONTROL_REAR_CHANNEL
, PLAYBACK_VOLUME1
},
899 { CONTROL_CENTER_LFE_CHANNEL
, PLAYBACK_VOLUME1
},
900 { CONTROL_UNKNOWN_CHANNEL
, PLAYBACK_VOLUME1
},
901 { 1, CAPTURE_CONTROL
},
904 void snd_ca0106_mixer_suspend(struct snd_ca0106
*chip
)
909 for (i
= 0; i
< NUM_SAVED_VOLUMES
; i
++)
911 snd_ca0106_ptr_read(chip
, saved_volumes
[i
].reg
,
912 saved_volumes
[i
].channel_id
);
915 void snd_ca0106_mixer_resume(struct snd_ca0106
*chip
)
919 for (i
= 0; i
< NUM_SAVED_VOLUMES
; i
++)
920 snd_ca0106_ptr_write(chip
, saved_volumes
[i
].reg
,
921 saved_volumes
[i
].channel_id
,
924 ca0106_spdif_enable(chip
);
925 ca0106_set_capture_source(chip
);
926 ca0106_set_i2c_capture_source(chip
, chip
->i2c_capture_source
, 1);
927 for (i
= 0; i
< 4; i
++)
928 ca0106_set_spdif_bits(chip
, i
);
929 if (chip
->details
->i2c_adc
)
930 ca0106_set_capture_mic_line_in(chip
);
932 #endif /* CONFIG_PM_SLEEP */