]> asedeno.scripts.mit.edu Git - linux.git/blob - sound/pci/ca0106/ca0106_mixer.c
ALSA: ca0106: More constifications
[linux.git] / sound / pci / ca0106 / ca0106_mixer.c
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
6  *
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)
45  *
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>
48  */
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>
60
61 #include "ca0106.h"
62
63 static void ca0106_spdif_enable(struct snd_ca0106 *emu)
64 {
65         unsigned int val;
66
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);
75
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);
84         }
85 }
86
87 static void ca0106_set_capture_source(struct snd_ca0106 *emu)
88 {
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);
94 }
95
96 static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
97                                           unsigned int val, int force)
98 {
99         unsigned int ngain, ogain;
100         u32 source;
101
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;
114 }
115
116 static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
117 {
118         u32 tmp;
119
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); */
131         }
132 }
133
134 static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
135 {
136         snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
137 }
138
139 /*
140  */
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);
143
144 #define snd_ca0106_shared_spdif_info    snd_ctl_boolean_mono_info
145
146 static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
147                                         struct snd_ctl_elem_value *ucontrol)
148 {
149         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
150
151         ucontrol->value.integer.value[0] = emu->spdif_enable;
152         return 0;
153 }
154
155 static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
156                                         struct snd_ctl_elem_value *ucontrol)
157 {
158         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
159         unsigned int val;
160         int change = 0;
161
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);
167         }
168         return change;
169 }
170
171 static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
172                                           struct snd_ctl_elem_info *uinfo)
173 {
174         static const char * const texts[6] = {
175                 "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
176         };
177
178         return snd_ctl_enum_info(uinfo, 1, 6, texts);
179 }
180
181 static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
182                                         struct snd_ctl_elem_value *ucontrol)
183 {
184         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
185
186         ucontrol->value.enumerated.item[0] = emu->capture_source;
187         return 0;
188 }
189
190 static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
191                                         struct snd_ctl_elem_value *ucontrol)
192 {
193         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
194         unsigned int val;
195         int change = 0;
196
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);
204         }
205         return change;
206 }
207
208 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
209                                           struct snd_ctl_elem_info *uinfo)
210 {
211         static const char * const texts[4] = {
212                 "Phone", "Mic", "Line in", "Aux"
213         };
214
215         return snd_ctl_enum_info(uinfo, 1, 4, texts);
216 }
217
218 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
219                                         struct snd_ctl_elem_value *ucontrol)
220 {
221         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
222
223         ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
224         return 0;
225 }
226
227 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
228                                         struct snd_ctl_elem_value *ucontrol)
229 {
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.
236          */
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);
243         }
244         return change;
245 }
246
247 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
248                                                struct snd_ctl_elem_info *uinfo)
249 {
250         static const char * const texts[2] = { "Side out", "Line in" };
251
252         return snd_ctl_enum_info(uinfo, 1, 2, texts);
253 }
254
255 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
256                                                struct snd_ctl_elem_info *uinfo)
257 {
258         static const char * const texts[2] = { "Line in", "Mic in" };
259
260         return snd_ctl_enum_info(uinfo, 1, 2, texts);
261 }
262
263 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
264                                         struct snd_ctl_elem_value *ucontrol)
265 {
266         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
267
268         ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
269         return 0;
270 }
271
272 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
273                                         struct snd_ctl_elem_value *ucontrol)
274 {
275         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
276         unsigned int val;
277         int change = 0;
278
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);
286         }
287         return change;
288 }
289
290 static const struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
291 {
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
297 };
298
299 static const struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out =
300 {
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
306 };
307
308
309 static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
310                                  struct snd_ctl_elem_info *uinfo)
311 {
312         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
313         uinfo->count = 1;
314         return 0;
315 }
316
317 static void decode_spdif_bits(unsigned char *status, unsigned int bits)
318 {
319         status[0] = (bits >> 0) & 0xff;
320         status[1] = (bits >> 8) & 0xff;
321         status[2] = (bits >> 16) & 0xff;
322         status[3] = (bits >> 24) & 0xff;
323 }
324
325 static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
326                                  struct snd_ctl_elem_value *ucontrol)
327 {
328         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
329         unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
330
331         decode_spdif_bits(ucontrol->value.iec958.status,
332                           emu->spdif_bits[idx]);
333         return 0;
334 }
335
336 static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
337                                  struct snd_ctl_elem_value *ucontrol)
338 {
339         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
340         unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
341
342         decode_spdif_bits(ucontrol->value.iec958.status,
343                           emu->spdif_str_bits[idx]);
344         return 0;
345 }
346
347 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
348                                       struct snd_ctl_elem_value *ucontrol)
349 {
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;
355 }
356
357 static unsigned int encode_spdif_bits(unsigned char *status)
358 {
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);
363 }
364
365 static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
366                                  struct snd_ctl_elem_value *ucontrol)
367 {
368         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
369         unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
370         unsigned int val;
371
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
377                  */
378                 emu->spdif_str_bits[idx] = val;
379                 ca0106_set_spdif_bits(emu, idx);
380                 return 1;
381         }
382         return 0;
383 }
384
385 static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
386                                  struct snd_ctl_elem_value *ucontrol)
387 {
388         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
389         unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
390         unsigned int val;
391
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;
397         }
398         return 0;
399 }
400
401 static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
402                                   struct snd_ctl_elem_info *uinfo)
403 {
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;
409 }
410
411 static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
412                                  struct snd_ctl_elem_value *ucontrol)
413 {
414         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
415         unsigned int value;
416         int channel_id, reg;
417
418         channel_id = (kcontrol->private_value >> 8) & 0xff;
419         reg = kcontrol->private_value & 0xff;
420
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;
425 }
426
427 static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
428                                  struct snd_ctl_elem_value *ucontrol)
429 {
430         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
431         unsigned int oval, nval;
432         int channel_id, reg;
433
434         channel_id = (kcontrol->private_value >> 8) & 0xff;
435         reg = kcontrol->private_value & 0xff;
436
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;
446 }
447
448 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
449                                   struct snd_ctl_elem_info *uinfo)
450 {
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;
456 }
457
458 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
459                                  struct snd_ctl_elem_value *ucontrol)
460 {
461         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
462         int source_id;
463
464         source_id = kcontrol->private_value;
465
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;
469 }
470
471 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
472                                  struct snd_ctl_elem_value *ucontrol)
473 {
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;
479
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;
490         }
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;
500         }
501
502         return change;
503 }
504
505 #define spi_mute_info   snd_ctl_boolean_mono_info
506
507 static int spi_mute_get(struct snd_kcontrol *kcontrol,
508                         struct snd_ctl_elem_value *ucontrol)
509 {
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;
513
514         ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
515         return 0;
516 }
517
518 static int spi_mute_put(struct snd_kcontrol *kcontrol,
519                         struct snd_ctl_elem_value *ucontrol)
520 {
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;
525
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;
535         }
536
537         ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
538         return ret ? -EINVAL : 1;
539 }
540
541 #define CA_VOLUME(xname,chid,reg) \
542 {                                                               \
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)                  \
551 }
552
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),
562
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),
571
572         CA_VOLUME("CAPTURE feedback Playback Volume",
573                   1, CAPTURE_CONTROL),
574
575         {
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
582         },
583         {
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
589         },
590         {
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
596         },
597         {
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
603         },
604         {
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
611         },
612         {
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
619         },
620 };
621
622 #define I2C_VOLUME(xname,chid) \
623 {                                                               \
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                                   \
632 }
633
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),
639 };
640
641 static const int spi_dmute_reg[] = {
642         SPI_DMUTE0_REG,
643         SPI_DMUTE1_REG,
644         SPI_DMUTE2_REG,
645         0,
646         SPI_DMUTE4_REG,
647 };
648 static const int spi_dmute_bit[] = {
649         SPI_DMUTE0_BIT,
650         SPI_DMUTE1_BIT,
651         SPI_DMUTE2_BIT,
652         0,
653         SPI_DMUTE4_BIT,
654 };
655
656 static struct snd_kcontrol_new
657 snd_ca0106_volume_spi_dac_ctl(const struct snd_ca0106_details *details,
658                               int channel_id)
659 {
660         struct snd_kcontrol_new spi_switch = {0};
661         int reg, bit;
662         int dac_id;
663
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;
669
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;
691         }
692         reg = spi_dmute_reg[dac_id];
693         bit = spi_dmute_bit[dac_id];
694
695         spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
696
697         return spi_switch;
698 }
699
700 static int remove_ctl(struct snd_card *card, const char *name)
701 {
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);
707 }
708
709 static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
710 {
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);
717 }
718
719 static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
720 {
721         struct snd_kcontrol *kctl = ctl_find(card, src);
722         if (kctl) {
723                 strcpy(kctl->id.name, dst);
724                 return 0;
725         }
726         return -ENOENT;
727 }
728
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;                            \
736                 }                                                       \
737         } while (0)
738
739 static
740 DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
741
742 static const char * const slave_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
753 };
754
755 static const char * const slave_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
762 };
763
764 static void add_slaves(struct snd_card *card,
765                        struct snd_kcontrol *master, const char * const *list)
766 {
767         for (; *list; list++) {
768                 struct snd_kcontrol *slave = ctl_find(card, *list);
769                 if (slave)
770                         snd_ctl_add_slave(master, slave);
771         }
772 }
773
774 int snd_ca0106_mixer(struct snd_ca0106 *emu)
775 {
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
803         };
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
816         };
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
823
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;
833         }
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;
844                 }
845         }
846
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_slaves(card, vmaster, slave_vols);
856
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_slaves(card, vmaster, slave_sws);
866         }
867
868         strcpy(card->mixername, "CA0106");
869         return 0;
870 }
871
872 #ifdef CONFIG_PM_SLEEP
873 struct ca0106_vol_tbl {
874         unsigned int channel_id;
875         unsigned int reg;
876 };
877
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 },
888 };
889
890 void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
891 {
892         int i;
893
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);
899 }
900
901 void snd_ca0106_mixer_resume(struct snd_ca0106  *chip)
902 {
903         int i;
904
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]);
909
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);
917 }
918 #endif /* CONFIG_PM_SLEEP */