Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ca0106_mixer.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 James Courtier-Dutton <[email protected]>
3  * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4  * Version: 0.0.18
5  *
6  * FEATURES currently supported:
7  * See ca0106_main.c for features.
8  *
9  * Changelog:
10  * Support interrupts per period.
11  * Removed noise from Center/LFE channel when in Analog mode.
12  * Rename and remove mixer controls.
13  * 0.0.6
14  * Use separate card based DMA buffer for periods table list.
15  * 0.0.7
16  * Change remove and rename ctrls into lists.
17  * 0.0.8
18  * Try to fix capture sources.
19  * 0.0.9
20  * Fix AC3 output.
21  * Enable S32_LE format support.
22  * 0.0.10
23  * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
24  * 0.0.11
25  * Add Model name recognition.
26  * 0.0.12
27  * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
28  * Remove redundent "voice" handling.
29  * 0.0.13
30  * Single trigger call for multi channels.
31  * 0.0.14
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.
36  * 0.0.15
37  * Separated ca0106.c into separate functional .c files.
38  * 0.0.16
39  * Modified Copyright message.
40  * 0.0.17
41  * Implement Mic and Line in Capture.
42  * 0.0.18
43  * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
44  *
45  * This code was initially based on code from ALSA's emu10k1x.c which is:
46  * Copyright (c) by Francisco Moraes <[email protected]>
47  *
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.
52  *
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.
57  *
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
61  *
62  */
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>
73 #include <asm/io.h>
74 
75 #include "ca0106.h"
76 
77 static void ca0106_spdif_enable(struct snd_ca0106 *emu)
78 {
79  unsigned int val;
80 
81  if (emu->spdif_enable) {
82  /* Digital */
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;
87  val = inl(emu->port + GPIO) & ~0x101;
88  outl(val, emu->port + GPIO);
89 
90  } else {
91  /* Analog */
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;
96  val = inl(emu->port + GPIO) | 0x101;
97  outl(val, emu->port + GPIO);
98  }
99 }
100 
101 static void ca0106_set_capture_source(struct snd_ca0106 *emu)
102 {
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);
108 }
109 
110 static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
111  unsigned int val, int force)
112 {
113  unsigned int ngain, ogain;
114  u32 source;
115 
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);
125  source = 1 << val;
126  snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
127  emu->i2c_capture_source = val;
128 }
129 
130 static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
131 {
132  u32 tmp;
133 
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;
137  tmp = tmp | 0x400;
138  outl(tmp, emu->port+GPIO);
139  /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
140  } else {
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); */
145  }
146 }
147 
148 static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
149 {
150  snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
151 }
152 
153 /*
154  */
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);
157 
158 #define snd_ca0106_shared_spdif_info snd_ctl_boolean_mono_info
159 
160 static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
161  struct snd_ctl_elem_value *ucontrol)
162 {
163  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
164 
165  ucontrol->value.integer.value[0] = emu->spdif_enable;
166  return 0;
167 }
168 
169 static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
170  struct snd_ctl_elem_value *ucontrol)
171 {
172  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
173  unsigned int val;
174  int change = 0;
175 
176  val = !!ucontrol->value.integer.value[0];
177  change = (emu->spdif_enable != val);
178  if (change) {
179  emu->spdif_enable = val;
180  ca0106_spdif_enable(emu);
181  }
182  return change;
183 }
184 
185 static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
186  struct snd_ctl_elem_info *uinfo)
187 {
188  static char *texts[6] = {
189  "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
190  };
191 
193  uinfo->count = 1;
194  uinfo->value.enumerated.items = 6;
195  if (uinfo->value.enumerated.item > 5)
196  uinfo->value.enumerated.item = 5;
197  strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
198  return 0;
199 }
200 
201 static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
202  struct snd_ctl_elem_value *ucontrol)
203 {
204  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
205 
206  ucontrol->value.enumerated.item[0] = emu->capture_source;
207  return 0;
208 }
209 
210 static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
211  struct snd_ctl_elem_value *ucontrol)
212 {
213  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
214  unsigned int val;
215  int change = 0;
216 
217  val = ucontrol->value.enumerated.item[0] ;
218  if (val >= 6)
219  return -EINVAL;
220  change = (emu->capture_source != val);
221  if (change) {
222  emu->capture_source = val;
223  ca0106_set_capture_source(emu);
224  }
225  return change;
226 }
227 
228 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
229  struct snd_ctl_elem_info *uinfo)
230 {
231  static char *texts[6] = {
232  "Phone", "Mic", "Line in", "Aux"
233  };
234 
236  uinfo->count = 1;
237  uinfo->value.enumerated.items = 4;
238  if (uinfo->value.enumerated.item > 3)
239  uinfo->value.enumerated.item = 3;
240  strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
241  return 0;
242 }
243 
244 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
245  struct snd_ctl_elem_value *ucontrol)
246 {
247  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
248 
249  ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
250  return 0;
251 }
252 
253 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
254  struct snd_ctl_elem_value *ucontrol)
255 {
256  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
257  unsigned int source_id;
258  int change = 0;
259  /* If the capture source has changed,
260  * update the capture volume from the cached value
261  * for the particular source.
262  */
263  source_id = ucontrol->value.enumerated.item[0] ;
264  if (source_id >= 4)
265  return -EINVAL;
266  change = (emu->i2c_capture_source != source_id);
267  if (change) {
268  ca0106_set_i2c_capture_source(emu, source_id, 0);
269  }
270  return change;
271 }
272 
273 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
274  struct snd_ctl_elem_info *uinfo)
275 {
276  static char *texts[2] = { "Side out", "Line in" };
277 
279  uinfo->count = 1;
280  uinfo->value.enumerated.items = 2;
281  if (uinfo->value.enumerated.item > 1)
282  uinfo->value.enumerated.item = 1;
283  strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
284  return 0;
285 }
286 
287 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
288  struct snd_ctl_elem_info *uinfo)
289 {
290  static char *texts[2] = { "Line in", "Mic in" };
291 
293  uinfo->count = 1;
294  uinfo->value.enumerated.items = 2;
295  if (uinfo->value.enumerated.item > 1)
296  uinfo->value.enumerated.item = 1;
297  strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
298  return 0;
299 }
300 
301 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
302  struct snd_ctl_elem_value *ucontrol)
303 {
304  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
305 
306  ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
307  return 0;
308 }
309 
310 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
311  struct snd_ctl_elem_value *ucontrol)
312 {
313  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
314  unsigned int val;
315  int change = 0;
316 
317  val = ucontrol->value.enumerated.item[0] ;
318  if (val > 1)
319  return -EINVAL;
320  change = (emu->capture_mic_line_in != val);
321  if (change) {
322  emu->capture_mic_line_in = val;
323  ca0106_set_capture_mic_line_in(emu);
324  }
325  return change;
326 }
327 
328 static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
329 {
331  .name = "Shared Mic/Line in Capture Switch",
332  .info = snd_ca0106_capture_mic_line_in_info,
333  .get = snd_ca0106_capture_mic_line_in_get,
334  .put = snd_ca0106_capture_mic_line_in_put
335 };
336 
337 static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
338 {
340  .name = "Shared Line in/Side out Capture Switch",
341  .info = snd_ca0106_capture_line_in_side_out_info,
342  .get = snd_ca0106_capture_mic_line_in_get,
343  .put = snd_ca0106_capture_mic_line_in_put
344 };
345 
346 
347 static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
348  struct snd_ctl_elem_info *uinfo)
349 {
351  uinfo->count = 1;
352  return 0;
353 }
354 
355 static void decode_spdif_bits(unsigned char *status, unsigned int bits)
356 {
357  status[0] = (bits >> 0) & 0xff;
358  status[1] = (bits >> 8) & 0xff;
359  status[2] = (bits >> 16) & 0xff;
360  status[3] = (bits >> 24) & 0xff;
361 }
362 
363 static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
364  struct snd_ctl_elem_value *ucontrol)
365 {
366  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
367  unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
368 
369  decode_spdif_bits(ucontrol->value.iec958.status,
370  emu->spdif_bits[idx]);
371  return 0;
372 }
373 
374 static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
375  struct snd_ctl_elem_value *ucontrol)
376 {
377  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
378  unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
379 
380  decode_spdif_bits(ucontrol->value.iec958.status,
381  emu->spdif_str_bits[idx]);
382  return 0;
383 }
384 
385 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
386  struct snd_ctl_elem_value *ucontrol)
387 {
388  ucontrol->value.iec958.status[0] = 0xff;
389  ucontrol->value.iec958.status[1] = 0xff;
390  ucontrol->value.iec958.status[2] = 0xff;
391  ucontrol->value.iec958.status[3] = 0xff;
392  return 0;
393 }
394 
395 static unsigned int encode_spdif_bits(unsigned char *status)
396 {
397  return ((unsigned int)status[0] << 0) |
398  ((unsigned int)status[1] << 8) |
399  ((unsigned int)status[2] << 16) |
400  ((unsigned int)status[3] << 24);
401 }
402 
403 static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
404  struct snd_ctl_elem_value *ucontrol)
405 {
406  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
407  unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
408  unsigned int val;
409 
410  val = encode_spdif_bits(ucontrol->value.iec958.status);
411  if (val != emu->spdif_bits[idx]) {
412  emu->spdif_bits[idx] = val;
413  /* FIXME: this isn't safe, but needed to keep the compatibility
414  * with older alsa-lib config
415  */
416  emu->spdif_str_bits[idx] = val;
417  ca0106_set_spdif_bits(emu, idx);
418  return 1;
419  }
420  return 0;
421 }
422 
423 static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
424  struct snd_ctl_elem_value *ucontrol)
425 {
426  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
427  unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
428  unsigned int val;
429 
430  val = encode_spdif_bits(ucontrol->value.iec958.status);
431  if (val != emu->spdif_str_bits[idx]) {
432  emu->spdif_str_bits[idx] = val;
433  ca0106_set_spdif_bits(emu, idx);
434  return 1;
435  }
436  return 0;
437 }
438 
439 static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
440  struct snd_ctl_elem_info *uinfo)
441 {
443  uinfo->count = 2;
444  uinfo->value.integer.min = 0;
445  uinfo->value.integer.max = 255;
446  return 0;
447 }
448 
449 static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
450  struct snd_ctl_elem_value *ucontrol)
451 {
452  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
453  unsigned int value;
454  int channel_id, reg;
455 
456  channel_id = (kcontrol->private_value >> 8) & 0xff;
457  reg = kcontrol->private_value & 0xff;
458 
459  value = snd_ca0106_ptr_read(emu, reg, channel_id);
460  ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
461  ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
462  return 0;
463 }
464 
465 static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
466  struct snd_ctl_elem_value *ucontrol)
467 {
468  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
469  unsigned int oval, nval;
470  int channel_id, reg;
471 
472  channel_id = (kcontrol->private_value >> 8) & 0xff;
473  reg = kcontrol->private_value & 0xff;
474 
475  oval = snd_ca0106_ptr_read(emu, reg, channel_id);
476  nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
477  ((0xff - ucontrol->value.integer.value[1]) << 16);
478  nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
479  ((0xff - ucontrol->value.integer.value[1]) );
480  if (oval == nval)
481  return 0;
482  snd_ca0106_ptr_write(emu, reg, channel_id, nval);
483  return 1;
484 }
485 
486 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
487  struct snd_ctl_elem_info *uinfo)
488 {
490  uinfo->count = 2;
491  uinfo->value.integer.min = 0;
492  uinfo->value.integer.max = 255;
493  return 0;
494 }
495 
496 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
497  struct snd_ctl_elem_value *ucontrol)
498 {
499  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
500  int source_id;
501 
502  source_id = kcontrol->private_value;
503 
504  ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
505  ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
506  return 0;
507 }
508 
509 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
510  struct snd_ctl_elem_value *ucontrol)
511 {
512  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
513  unsigned int ogain;
514  unsigned int ngain;
515  int source_id;
516  int change = 0;
517 
518  source_id = kcontrol->private_value;
519  ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
520  ngain = ucontrol->value.integer.value[0];
521  if (ngain > 0xff)
522  return -EINVAL;
523  if (ogain != ngain) {
524  if (emu->i2c_capture_source == source_id)
525  snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
526  emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
527  change = 1;
528  }
529  ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
530  ngain = ucontrol->value.integer.value[1];
531  if (ngain > 0xff)
532  return -EINVAL;
533  if (ogain != ngain) {
534  if (emu->i2c_capture_source == source_id)
535  snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
536  emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
537  change = 1;
538  }
539 
540  return change;
541 }
542 
543 #define spi_mute_info snd_ctl_boolean_mono_info
544 
545 static int spi_mute_get(struct snd_kcontrol *kcontrol,
546  struct snd_ctl_elem_value *ucontrol)
547 {
548  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
549  unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
550  unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
551 
552  ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
553  return 0;
554 }
555 
556 static int spi_mute_put(struct snd_kcontrol *kcontrol,
557  struct snd_ctl_elem_value *ucontrol)
558 {
559  struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
560  unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
561  unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
562  int ret;
563 
564  ret = emu->spi_dac_reg[reg] & bit;
565  if (ucontrol->value.integer.value[0]) {
566  if (!ret) /* bit already cleared, do nothing */
567  return 0;
568  emu->spi_dac_reg[reg] &= ~bit;
569  } else {
570  if (ret) /* bit already set, do nothing */
571  return 0;
572  emu->spi_dac_reg[reg] |= bit;
573  }
574 
575  ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
576  return ret ? -EINVAL : 1;
577 }
578 
579 #define CA_VOLUME(xname,chid,reg) \
580 { \
581  .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
582  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
583  SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
584  .info = snd_ca0106_volume_info, \
585  .get = snd_ca0106_volume_get, \
586  .put = snd_ca0106_volume_put, \
587  .tlv = { .p = snd_ca0106_db_scale1 }, \
588  .private_value = ((chid) << 8) | (reg) \
589 }
590 
591 static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
592  CA_VOLUME("Analog Front Playback Volume",
594  CA_VOLUME("Analog Rear Playback Volume",
596  CA_VOLUME("Analog Center/LFE Playback Volume",
598  CA_VOLUME("Analog Side Playback Volume",
600 
601  CA_VOLUME("IEC958 Front Playback Volume",
603  CA_VOLUME("IEC958 Rear Playback Volume",
605  CA_VOLUME("IEC958 Center/LFE Playback Volume",
607  CA_VOLUME("IEC958 Unknown Playback Volume",
609 
610  CA_VOLUME("CAPTURE feedback Playback Volume",
611  1, CAPTURE_CONTROL),
612 
613  {
614  .access = SNDRV_CTL_ELEM_ACCESS_READ,
615  .iface = SNDRV_CTL_ELEM_IFACE_PCM,
616  .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
617  .count = 4,
618  .info = snd_ca0106_spdif_info,
619  .get = snd_ca0106_spdif_get_mask
620  },
621  {
623  .name = "IEC958 Playback Switch",
625  .get = snd_ca0106_shared_spdif_get,
626  .put = snd_ca0106_shared_spdif_put
627  },
628  {
630  .name = "Digital Source Capture Enum",
631  .info = snd_ca0106_capture_source_info,
632  .get = snd_ca0106_capture_source_get,
633  .put = snd_ca0106_capture_source_put
634  },
635  {
637  .name = "Analog Source Capture Enum",
638  .info = snd_ca0106_i2c_capture_source_info,
639  .get = snd_ca0106_i2c_capture_source_get,
640  .put = snd_ca0106_i2c_capture_source_put
641  },
642  {
643  .iface = SNDRV_CTL_ELEM_IFACE_PCM,
645  .count = 4,
646  .info = snd_ca0106_spdif_info,
647  .get = snd_ca0106_spdif_get_default,
648  .put = snd_ca0106_spdif_put_default
649  },
650  {
651  .iface = SNDRV_CTL_ELEM_IFACE_PCM,
652  .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
653  .count = 4,
654  .info = snd_ca0106_spdif_info,
655  .get = snd_ca0106_spdif_get_stream,
656  .put = snd_ca0106_spdif_put_stream
657  },
658 };
659 
660 #define I2C_VOLUME(xname,chid) \
661 { \
662  .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
663  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
664  SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
665  .info = snd_ca0106_i2c_volume_info, \
666  .get = snd_ca0106_i2c_volume_get, \
667  .put = snd_ca0106_i2c_volume_put, \
668  .tlv = { .p = snd_ca0106_db_scale2 }, \
669  .private_value = chid \
670 }
671 
672 static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = {
673  I2C_VOLUME("Phone Capture Volume", 0),
674  I2C_VOLUME("Mic Capture Volume", 1),
675  I2C_VOLUME("Line in Capture Volume", 2),
676  I2C_VOLUME("Aux Capture Volume", 3),
677 };
678 
679 static const int spi_dmute_reg[] = {
683  0,
685 };
686 static const int spi_dmute_bit[] = {
690  0,
692 };
693 
694 static struct snd_kcontrol_new __devinit
695 snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details,
696  int channel_id)
697 {
698  struct snd_kcontrol_new spi_switch = {0};
699  int reg, bit;
700  int dac_id;
701 
702  spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
704  spi_switch.info = spi_mute_info;
705  spi_switch.get = spi_mute_get;
706  spi_switch.put = spi_mute_put;
707 
708  switch (channel_id) {
709  case PCM_FRONT_CHANNEL:
710  spi_switch.name = "Analog Front Playback Switch";
711  dac_id = (details->spi_dac & 0xf000) >> (4 * 3);
712  break;
713  case PCM_REAR_CHANNEL:
714  spi_switch.name = "Analog Rear Playback Switch";
715  dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
716  break;
718  spi_switch.name = "Analog Center/LFE Playback Switch";
719  dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
720  break;
721  case PCM_UNKNOWN_CHANNEL:
722  spi_switch.name = "Analog Side Playback Switch";
723  dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
724  break;
725  default:
726  /* Unused channel */
727  spi_switch.name = NULL;
728  dac_id = 0;
729  }
730  reg = spi_dmute_reg[dac_id];
731  bit = spi_dmute_bit[dac_id];
732 
733  spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
734 
735  return spi_switch;
736 }
737 
738 static int __devinit remove_ctl(struct snd_card *card, const char *name)
739 {
740  struct snd_ctl_elem_id id;
741  memset(&id, 0, sizeof(id));
742  strcpy(id.name, name);
743  id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
744  return snd_ctl_remove_id(card, &id);
745 }
746 
747 static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, const char *name)
748 {
749  struct snd_ctl_elem_id sid;
750  memset(&sid, 0, sizeof(sid));
751  /* FIXME: strcpy is bad. */
752  strcpy(sid.name, name);
754  return snd_ctl_find_id(card, &sid);
755 }
756 
757 static int __devinit rename_ctl(struct snd_card *card, const char *src, const char *dst)
758 {
759  struct snd_kcontrol *kctl = ctl_find(card, src);
760  if (kctl) {
761  strcpy(kctl->id.name, dst);
762  return 0;
763  }
764  return -ENOENT;
765 }
766 
767 #define ADD_CTLS(emu, ctls) \
768  do { \
769  int i, _err; \
770  for (i = 0; i < ARRAY_SIZE(ctls); i++) { \
771  _err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
772  if (_err < 0) \
773  return _err; \
774  } \
775  } while (0)
776 
777 static __devinitdata
778 DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
779 
780 static char *slave_vols[] __devinitdata = {
781  "Analog Front Playback Volume",
782  "Analog Rear Playback Volume",
783  "Analog Center/LFE Playback Volume",
784  "Analog Side Playback Volume",
785  "IEC958 Front Playback Volume",
786  "IEC958 Rear Playback Volume",
787  "IEC958 Center/LFE Playback Volume",
788  "IEC958 Unknown Playback Volume",
789  "CAPTURE feedback Playback Volume",
790  NULL
791 };
792 
793 static char *slave_sws[] __devinitdata = {
794  "Analog Front Playback Switch",
795  "Analog Rear Playback Switch",
796  "Analog Center/LFE Playback Switch",
797  "Analog Side Playback Switch",
798  "IEC958 Playback Switch",
799  NULL
800 };
801 
802 static void __devinit add_slaves(struct snd_card *card,
803  struct snd_kcontrol *master, char **list)
804 {
805  for (; *list; list++) {
806  struct snd_kcontrol *slave = ctl_find(card, *list);
807  if (slave)
808  snd_ctl_add_slave(master, slave);
809  }
810 }
811 
813 {
814  int err;
815  struct snd_card *card = emu->card;
816  char **c;
817  struct snd_kcontrol *vmaster;
818  static char *ca0106_remove_ctls[] = {
819  "Master Mono Playback Switch",
820  "Master Mono Playback Volume",
821  "3D Control - Switch",
822  "3D Control Sigmatel - Depth",
823  "PCM Playback Switch",
824  "PCM Playback Volume",
825  "CD Playback Switch",
826  "CD Playback Volume",
827  "Phone Playback Switch",
828  "Phone Playback Volume",
829  "Video Playback Switch",
830  "Video Playback Volume",
831  "Beep Playback Switch",
832  "Beep Playback Volume",
833  "Mono Output Select",
834  "Capture Source",
835  "Capture Switch",
836  "Capture Volume",
837  "External Amplifier",
838  "Sigmatel 4-Speaker Stereo Playback Switch",
839  "Surround Phase Inversion Playback Switch",
840  NULL
841  };
842  static char *ca0106_rename_ctls[] = {
843  "Master Playback Switch", "Capture Switch",
844  "Master Playback Volume", "Capture Volume",
845  "Line Playback Switch", "AC97 Line Capture Switch",
846  "Line Playback Volume", "AC97 Line Capture Volume",
847  "Aux Playback Switch", "AC97 Aux Capture Switch",
848  "Aux Playback Volume", "AC97 Aux Capture Volume",
849  "Mic Playback Switch", "AC97 Mic Capture Switch",
850  "Mic Playback Volume", "AC97 Mic Capture Volume",
851  "Mic Select", "AC97 Mic Select",
852  "Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
853  NULL
854  };
855 #if 1
856  for (c = ca0106_remove_ctls; *c; c++)
857  remove_ctl(card, *c);
858  for (c = ca0106_rename_ctls; *c; c += 2)
859  rename_ctl(card, c[0], c[1]);
860 #endif
861 
862  ADD_CTLS(emu, snd_ca0106_volume_ctls);
863  if (emu->details->i2c_adc == 1) {
864  ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
865  if (emu->details->gpio_type == 1)
866  err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
867  else /* gpio_type == 2 */
868  err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
869  if (err < 0)
870  return err;
871  }
872  if (emu->details->spi_dac) {
873  int i;
874  for (i = 0;; i++) {
875  struct snd_kcontrol_new ctl;
876  ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
877  if (!ctl.name)
878  break;
879  err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
880  if (err < 0)
881  return err;
882  }
883  }
884 
885  /* Create virtual master controls */
886  vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
887  snd_ca0106_master_db_scale);
888  if (!vmaster)
889  return -ENOMEM;
890  err = snd_ctl_add(card, vmaster);
891  if (err < 0)
892  return err;
893  add_slaves(card, vmaster, slave_vols);
894 
895  if (emu->details->spi_dac) {
896  vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
897  NULL);
898  if (!vmaster)
899  return -ENOMEM;
900  err = snd_ctl_add(card, vmaster);
901  if (err < 0)
902  return err;
903  add_slaves(card, vmaster, slave_sws);
904  }
905 
906  strcpy(card->mixername, "CA0106");
907  return 0;
908 }
909 
910 #ifdef CONFIG_PM_SLEEP
911 struct ca0106_vol_tbl {
912  unsigned int channel_id;
913  unsigned int reg;
914 };
915 
916 static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
925  { 1, CAPTURE_CONTROL },
926 };
927 
929 {
930  int i;
931 
932  /* save volumes */
933  for (i = 0; i < NUM_SAVED_VOLUMES; i++)
934  chip->saved_vol[i] =
935  snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
936  saved_volumes[i].channel_id);
937 }
938 
939 void snd_ca0106_mixer_resume(struct snd_ca0106 *chip)
940 {
941  int i;
942 
943  for (i = 0; i < NUM_SAVED_VOLUMES; i++)
944  snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
945  saved_volumes[i].channel_id,
946  chip->saved_vol[i]);
947 
948  ca0106_spdif_enable(chip);
949  ca0106_set_capture_source(chip);
950  ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
951  for (i = 0; i < 4; i++)
952  ca0106_set_spdif_bits(chip, i);
953  if (chip->details->i2c_adc)
954  ca0106_set_capture_mic_line_in(chip);
955 }
956 #endif /* CONFIG_PM_SLEEP */