Merge tag 'x86-urgent-2020-08-15' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux/fpc-iii.git] / sound / pci / ca0106 / ca0106_mixer.c
blobc852c6a75b917399889e123176e1d0068431deba
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
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
5 * Version: 0.0.18
7 * FEATURES currently supported:
8 * See ca0106_main.c for features.
9 *
10 * Changelog:
11 * Support interrupts per period.
12 * Removed noise from Center/LFE channel when in Analog mode.
13 * Rename and remove mixer controls.
14 * 0.0.6
15 * Use separate card based DMA buffer for periods table list.
16 * 0.0.7
17 * Change remove and rename ctrls into lists.
18 * 0.0.8
19 * Try to fix capture sources.
20 * 0.0.9
21 * Fix AC3 output.
22 * Enable S32_LE format support.
23 * 0.0.10
24 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
25 * 0.0.11
26 * Add Model name recognition.
27 * 0.0.12
28 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
29 * Remove redundent "voice" handling.
30 * 0.0.13
31 * Single trigger call for multi channels.
32 * 0.0.14
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.
37 * 0.0.15
38 * Separated ca0106.c into separate functional .c files.
39 * 0.0.16
40 * Modified Copyright message.
41 * 0.0.17
42 * Implement Mic and Line in Capture.
43 * 0.0.18
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>
59 #include <linux/io.h>
61 #include "ca0106.h"
63 static void ca0106_spdif_enable(struct snd_ca0106 *emu)
65 unsigned int val;
67 if (emu->spdif_enable) {
68 /* Digital */
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);
76 } else {
77 /* Analog */
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;
100 u32 source;
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);
111 source = 1 << val;
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)
118 u32 tmp;
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;
123 tmp = tmp | 0x400;
124 outl(tmp, emu->port+GPIO);
125 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
126 } else {
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;
152 return 0;
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);
159 unsigned int val;
160 int change = 0;
162 val = !!ucontrol->value.integer.value[0];
163 change = (emu->spdif_enable != val);
164 if (change) {
165 emu->spdif_enable = val;
166 ca0106_spdif_enable(emu);
168 return change;
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;
187 return 0;
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);
194 unsigned int val;
195 int change = 0;
197 val = ucontrol->value.enumerated.item[0] ;
198 if (val >= 6)
199 return -EINVAL;
200 change = (emu->capture_source != val);
201 if (change) {
202 emu->capture_source = val;
203 ca0106_set_capture_source(emu);
205 return change;
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;
224 return 0;
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;
232 int change = 0;
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] ;
238 if (source_id >= 4)
239 return -EINVAL;
240 change = (emu->i2c_capture_source != source_id);
241 if (change) {
242 ca0106_set_i2c_capture_source(emu, source_id, 0);
244 return change;
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;
269 return 0;
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);
276 unsigned int val;
277 int change = 0;
279 val = ucontrol->value.enumerated.item[0] ;
280 if (val > 1)
281 return -EINVAL;
282 change = (emu->capture_mic_line_in != val);
283 if (change) {
284 emu->capture_mic_line_in = val;
285 ca0106_set_capture_mic_line_in(emu);
287 return change;
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;
313 uinfo->count = 1;
314 return 0;
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]);
333 return 0;
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]);
344 return 0;
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;
354 return 0;
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);
370 unsigned int val;
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);
380 return 1;
382 return 0;
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);
390 unsigned int val;
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);
396 return 1;
398 return 0;
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;
405 uinfo->count = 2;
406 uinfo->value.integer.min = 0;
407 uinfo->value.integer.max = 255;
408 return 0;
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);
415 unsigned int value;
416 int channel_id, reg;
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 */
424 return 0;
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;
432 int channel_id, reg;
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]) );
442 if (oval == nval)
443 return 0;
444 snd_ca0106_ptr_write(emu, reg, channel_id, nval);
445 return 1;
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;
452 uinfo->count = 2;
453 uinfo->value.integer.min = 0;
454 uinfo->value.integer.max = 255;
455 return 0;
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);
462 int source_id;
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];
468 return 0;
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);
475 unsigned int ogain;
476 unsigned int ngain;
477 int source_id;
478 int change = 0;
480 source_id = kcontrol->private_value;
481 ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
482 ngain = ucontrol->value.integer.value[0];
483 if (ngain > 0xff)
484 return -EINVAL;
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];
489 change = 1;
491 ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
492 ngain = ucontrol->value.integer.value[1];
493 if (ngain > 0xff)
494 return -EINVAL;
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];
499 change = 1;
502 return change;
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);
515 return 0;
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;
524 int ret;
526 ret = emu->spi_dac_reg[reg] & bit;
527 if (ucontrol->value.integer.value[0]) {
528 if (!ret) /* bit already cleared, do nothing */
529 return 0;
530 emu->spi_dac_reg[reg] &= ~bit;
531 } else {
532 if (ret) /* bit already set, do nothing */
533 return 0;
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",
573 1, CAPTURE_CONTROL),
576 .access = SNDRV_CTL_ELEM_ACCESS_READ,
577 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
578 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
579 .count = 4,
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),
607 .count = 4,
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),
615 .count = 4,
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[] = {
642 SPI_DMUTE0_REG,
643 SPI_DMUTE1_REG,
644 SPI_DMUTE2_REG,
646 SPI_DMUTE4_REG,
648 static const int spi_dmute_bit[] = {
649 SPI_DMUTE0_BIT,
650 SPI_DMUTE1_BIT,
651 SPI_DMUTE2_BIT,
653 SPI_DMUTE4_BIT,
656 static struct snd_kcontrol_new
657 snd_ca0106_volume_spi_dac_ctl(const struct snd_ca0106_details *details,
658 int channel_id)
660 struct snd_kcontrol_new spi_switch = {0};
661 int reg, bit;
662 int dac_id;
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);
674 break;
675 case PCM_REAR_CHANNEL:
676 spi_switch.name = "Analog Rear Playback Switch";
677 dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
678 break;
679 case PCM_CENTER_LFE_CHANNEL:
680 spi_switch.name = "Analog Center/LFE Playback Switch";
681 dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
682 break;
683 case PCM_UNKNOWN_CHANNEL:
684 spi_switch.name = "Analog Side Playback Switch";
685 dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
686 break;
687 default:
688 /* Unused channel */
689 spi_switch.name = NULL;
690 dac_id = 0;
692 reg = spi_dmute_reg[dac_id];
693 bit = spi_dmute_bit[dac_id];
695 spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
697 return spi_switch;
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);
722 if (kctl) {
723 strcpy(kctl->id.name, dst);
724 return 0;
726 return -ENOENT;
729 #define ADD_CTLS(emu, ctls) \
730 do { \
731 int i, _err; \
732 for (i = 0; i < ARRAY_SIZE(ctls); i++) { \
733 _err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
734 if (_err < 0) \
735 return _err; \
737 } while (0)
739 static
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",
752 NULL
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",
761 NULL
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);
769 if (follower)
770 snd_ctl_add_follower(master, follower);
774 int snd_ca0106_mixer(struct snd_ca0106 *emu)
776 int err;
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",
796 "Capture Source",
797 "Capture Switch",
798 "Capture Volume",
799 "External Amplifier",
800 "Sigmatel 4-Speaker Stereo Playback Switch",
801 "Surround Phase Inversion Playback Switch",
802 NULL
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)",
815 NULL
817 #if 1
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]);
822 #endif
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));
831 if (err < 0)
832 return err;
834 if (emu->details->spi_dac) {
835 int i;
836 for (i = 0;; i++) {
837 struct snd_kcontrol_new ctl;
838 ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
839 if (!ctl.name)
840 break;
841 err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
842 if (err < 0)
843 return err;
847 /* Create virtual master controls */
848 vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
849 snd_ca0106_master_db_scale);
850 if (!vmaster)
851 return -ENOMEM;
852 err = snd_ctl_add(card, vmaster);
853 if (err < 0)
854 return err;
855 add_followers(card, vmaster, follower_vols);
857 if (emu->details->spi_dac) {
858 vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
859 NULL);
860 if (!vmaster)
861 return -ENOMEM;
862 err = snd_ctl_add(card, vmaster);
863 if (err < 0)
864 return err;
865 add_followers(card, vmaster, follower_sws);
868 strcpy(card->mixername, "CA0106");
869 return 0;
872 #ifdef CONFIG_PM_SLEEP
873 struct ca0106_vol_tbl {
874 unsigned int channel_id;
875 unsigned int reg;
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)
892 int i;
894 /* save volumes */
895 for (i = 0; i < NUM_SAVED_VOLUMES; i++)
896 chip->saved_vol[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)
903 int i;
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,
908 chip->saved_vol[i]);
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 */