Loading...
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
63static 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
87static 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
96static 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
116static 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
134static 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 */
141static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
142static 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
146static 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
155static 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
171static 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
181static 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
190static 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
208static 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
218static 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
227static 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
247static 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
255static 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
263static 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
272static 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
290static 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
299static 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
309static 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
317static 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
325static 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
336static 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
347static 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
357static 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
365static 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
385static 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
401static 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
411static 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
427static 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
448static 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
458static 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
471static 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
507static 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
518static 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
553static 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
634static 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
641static const int spi_dmute_reg[] = {
642 SPI_DMUTE0_REG,
643 SPI_DMUTE1_REG,
644 SPI_DMUTE2_REG,
645 0,
646 SPI_DMUTE4_REG,
647};
648static 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
656static struct snd_kcontrol_new
657snd_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
700static 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
709static 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
719static 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
739static
740DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
741
742static 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
753};
754
755static 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
762};
763
764static void add_followers(struct snd_card *card,
765 struct snd_kcontrol *master, const char * const *list)
766{
767 for (; *list; list++) {
768 struct snd_kcontrol *follower = ctl_find(card, *list);
769 if (follower)
770 snd_ctl_add_follower(master, follower);
771 }
772}
773
774int 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_followers(card, vmaster, follower_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_followers(card, vmaster, follower_sws);
866 }
867
868 strcpy(card->mixername, "CA0106");
869 return 0;
870}
871
872#ifdef CONFIG_PM_SLEEP
873struct ca0106_vol_tbl {
874 unsigned int channel_id;
875 unsigned int reg;
876};
877
878static 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
890void 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
901void 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 */
1/*
2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
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 <fmoraes@nc.rr.com>
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
77static 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;
86 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
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;
95 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
96 val = inl(emu->port + GPIO) | 0x101;
97 outl(val, emu->port + GPIO);
98 }
99}
100
101static 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
110static 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
130static 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
148static 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 */
155static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
156static 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
160static 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
169static 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
185static 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
192 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
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
201static 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
210static 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
228static 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
235 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
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
244static 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
253static 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
273static 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
278 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
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
287static 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
292 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
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
301static 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
310static 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
328static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
329{
330 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
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
337static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out =
338{
339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
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
347static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
348 struct snd_ctl_elem_info *uinfo)
349{
350 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
351 uinfo->count = 1;
352 return 0;
353}
354
355static 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
363static 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
374static 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
385static 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
395static 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
403static 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
423static 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
439static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
440 struct snd_ctl_elem_info *uinfo)
441{
442 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
443 uinfo->count = 2;
444 uinfo->value.integer.min = 0;
445 uinfo->value.integer.max = 255;
446 return 0;
447}
448
449static 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
465static 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
486static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_info *uinfo)
488{
489 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
490 uinfo->count = 2;
491 uinfo->value.integer.min = 0;
492 uinfo->value.integer.max = 255;
493 return 0;
494}
495
496static 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
509static 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
545static 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
556static 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
591static struct snd_kcontrol_new snd_ca0106_volume_ctls[] = {
592 CA_VOLUME("Analog Front Playback Volume",
593 CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
594 CA_VOLUME("Analog Rear Playback Volume",
595 CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
596 CA_VOLUME("Analog Center/LFE Playback Volume",
597 CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
598 CA_VOLUME("Analog Side Playback Volume",
599 CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
600
601 CA_VOLUME("IEC958 Front Playback Volume",
602 CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
603 CA_VOLUME("IEC958 Rear Playback Volume",
604 CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
605 CA_VOLUME("IEC958 Center/LFE Playback Volume",
606 CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
607 CA_VOLUME("IEC958 Unknown Playback Volume",
608 CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
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 {
622 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
623 .name = "IEC958 Playback Switch",
624 .info = snd_ca0106_shared_spdif_info,
625 .get = snd_ca0106_shared_spdif_get,
626 .put = snd_ca0106_shared_spdif_put
627 },
628 {
629 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
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 {
636 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
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,
644 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
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
672static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] = {
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
679static const int spi_dmute_reg[] = {
680 SPI_DMUTE0_REG,
681 SPI_DMUTE1_REG,
682 SPI_DMUTE2_REG,
683 0,
684 SPI_DMUTE4_REG,
685};
686static const int spi_dmute_bit[] = {
687 SPI_DMUTE0_BIT,
688 SPI_DMUTE1_BIT,
689 SPI_DMUTE2_BIT,
690 0,
691 SPI_DMUTE4_BIT,
692};
693
694static struct snd_kcontrol_new
695snd_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;
703 spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
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;
717 case PCM_CENTER_LFE_CHANNEL:
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
738static int 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
747static struct snd_kcontrol *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);
753 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
754 return snd_ctl_find_id(card, &sid);
755}
756
757static int 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
777static
778DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
779
780static char *slave_vols[] = {
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
793static char *slave_sws[] = {
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
802static void 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
812int snd_ca0106_mixer(struct snd_ca0106 *emu)
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
911struct ca0106_vol_tbl {
912 unsigned int channel_id;
913 unsigned int reg;
914};
915
916static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
917 { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
918 { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
919 { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
920 { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
921 { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
922 { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
923 { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
924 { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
925 { 1, CAPTURE_CONTROL },
926};
927
928void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
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
939void 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 */