Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
0004  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
0005  *  Version: 0.0.18
0006  *
0007  *  FEATURES currently supported:
0008  *    See ca0106_main.c for features.
0009  * 
0010  *  Changelog:
0011  *    Support interrupts per period.
0012  *    Removed noise from Center/LFE channel when in Analog mode.
0013  *    Rename and remove mixer controls.
0014  *  0.0.6
0015  *    Use separate card based DMA buffer for periods table list.
0016  *  0.0.7
0017  *    Change remove and rename ctrls into lists.
0018  *  0.0.8
0019  *    Try to fix capture sources.
0020  *  0.0.9
0021  *    Fix AC3 output.
0022  *    Enable S32_LE format support.
0023  *  0.0.10
0024  *    Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
0025  *  0.0.11
0026  *    Add Model name recognition.
0027  *  0.0.12
0028  *    Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
0029  *    Remove redundent "voice" handling.
0030  *  0.0.13
0031  *    Single trigger call for multi channels.
0032  *  0.0.14
0033  *    Set limits based on what the sound card hardware can do.
0034  *    playback periods_min=2, periods_max=8
0035  *    capture hw constraints require period_size = n * 64 bytes.
0036  *    playback hw constraints require period_size = n * 64 bytes.
0037  *  0.0.15
0038  *    Separated ca0106.c into separate functional .c files.
0039  *  0.0.16
0040  *    Modified Copyright message.
0041  *  0.0.17
0042  *    Implement Mic and Line in Capture.
0043  *  0.0.18
0044  *    Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
0045  *
0046  *  This code was initially based on code from ALSA's emu10k1x.c which is:
0047  *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
0048  */
0049 #include <linux/delay.h>
0050 #include <linux/init.h>
0051 #include <linux/interrupt.h>
0052 #include <linux/moduleparam.h>
0053 #include <sound/core.h>
0054 #include <sound/initval.h>
0055 #include <sound/pcm.h>
0056 #include <sound/ac97_codec.h>
0057 #include <sound/info.h>
0058 #include <sound/tlv.h>
0059 #include <linux/io.h>
0060 
0061 #include "ca0106.h"
0062 
0063 static void ca0106_spdif_enable(struct snd_ca0106 *emu)
0064 {
0065     unsigned int val;
0066 
0067     if (emu->spdif_enable) {
0068         /* Digital */
0069         snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
0070         snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
0071         val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
0072         snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
0073         val = inl(emu->port + CA0106_GPIO) & ~0x101;
0074         outl(val, emu->port + CA0106_GPIO);
0075 
0076     } else {
0077         /* Analog */
0078         snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
0079         snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
0080         val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
0081         snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
0082         val = inl(emu->port + CA0106_GPIO) | 0x101;
0083         outl(val, emu->port + CA0106_GPIO);
0084     }
0085 }
0086 
0087 static void ca0106_set_capture_source(struct snd_ca0106 *emu)
0088 {
0089     unsigned int val = emu->capture_source;
0090     unsigned int source, mask;
0091     source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
0092     mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
0093     snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
0094 }
0095 
0096 static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
0097                       unsigned int val, int force)
0098 {
0099     unsigned int ngain, ogain;
0100     u32 source;
0101 
0102     snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
0103     ngain = emu->i2c_capture_volume[val][0]; /* Left */
0104     ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
0105     if (force || ngain != ogain)
0106         snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
0107     ngain = emu->i2c_capture_volume[val][1]; /* Right */
0108     ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
0109     if (force || ngain != ogain)
0110         snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
0111     source = 1 << val;
0112     snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
0113     emu->i2c_capture_source = val;
0114 }
0115 
0116 static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
0117 {
0118     u32 tmp;
0119 
0120     if (emu->capture_mic_line_in) {
0121         /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
0122         tmp = inl(emu->port + CA0106_GPIO) & ~0x400;
0123         tmp = tmp | 0x400;
0124         outl(tmp, emu->port + CA0106_GPIO);
0125         /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
0126     } else {
0127         /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
0128         tmp = inl(emu->port + CA0106_GPIO) & ~0x400;
0129         outl(tmp, emu->port + CA0106_GPIO);
0130         /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
0131     }
0132 }
0133 
0134 static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
0135 {
0136     snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
0137 }
0138 
0139 /*
0140  */
0141 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
0142 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
0143 
0144 #define snd_ca0106_shared_spdif_info    snd_ctl_boolean_mono_info
0145 
0146 static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
0147                     struct snd_ctl_elem_value *ucontrol)
0148 {
0149     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0150 
0151     ucontrol->value.integer.value[0] = emu->spdif_enable;
0152     return 0;
0153 }
0154 
0155 static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
0156                     struct snd_ctl_elem_value *ucontrol)
0157 {
0158     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0159     unsigned int val;
0160     int change = 0;
0161 
0162     val = !!ucontrol->value.integer.value[0];
0163     change = (emu->spdif_enable != val);
0164     if (change) {
0165         emu->spdif_enable = val;
0166         ca0106_spdif_enable(emu);
0167     }
0168         return change;
0169 }
0170 
0171 static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
0172                       struct snd_ctl_elem_info *uinfo)
0173 {
0174     static const char * const texts[6] = {
0175         "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
0176     };
0177 
0178     return snd_ctl_enum_info(uinfo, 1, 6, texts);
0179 }
0180 
0181 static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
0182                     struct snd_ctl_elem_value *ucontrol)
0183 {
0184     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0185 
0186     ucontrol->value.enumerated.item[0] = emu->capture_source;
0187     return 0;
0188 }
0189 
0190 static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
0191                     struct snd_ctl_elem_value *ucontrol)
0192 {
0193     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0194     unsigned int val;
0195     int change = 0;
0196 
0197     val = ucontrol->value.enumerated.item[0] ;
0198     if (val >= 6)
0199         return -EINVAL;
0200     change = (emu->capture_source != val);
0201     if (change) {
0202         emu->capture_source = val;
0203         ca0106_set_capture_source(emu);
0204     }
0205         return change;
0206 }
0207 
0208 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
0209                       struct snd_ctl_elem_info *uinfo)
0210 {
0211     static const char * const texts[4] = {
0212         "Phone", "Mic", "Line in", "Aux"
0213     };
0214 
0215     return snd_ctl_enum_info(uinfo, 1, 4, texts);
0216 }
0217 
0218 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
0219                     struct snd_ctl_elem_value *ucontrol)
0220 {
0221     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0222 
0223     ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
0224     return 0;
0225 }
0226 
0227 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
0228                     struct snd_ctl_elem_value *ucontrol)
0229 {
0230     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0231     unsigned int source_id;
0232     int change = 0;
0233     /* If the capture source has changed,
0234      * update the capture volume from the cached value
0235      * for the particular source.
0236      */
0237     source_id = ucontrol->value.enumerated.item[0] ;
0238     if (source_id >= 4)
0239         return -EINVAL;
0240     change = (emu->i2c_capture_source != source_id);
0241     if (change) {
0242         ca0106_set_i2c_capture_source(emu, source_id, 0);
0243     }
0244         return change;
0245 }
0246 
0247 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
0248                            struct snd_ctl_elem_info *uinfo)
0249 {
0250     static const char * const texts[2] = { "Side out", "Line in" };
0251 
0252     return snd_ctl_enum_info(uinfo, 1, 2, texts);
0253 }
0254 
0255 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
0256                            struct snd_ctl_elem_info *uinfo)
0257 {
0258     static const char * const texts[2] = { "Line in", "Mic in" };
0259 
0260     return snd_ctl_enum_info(uinfo, 1, 2, texts);
0261 }
0262 
0263 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
0264                     struct snd_ctl_elem_value *ucontrol)
0265 {
0266     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0267 
0268     ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
0269     return 0;
0270 }
0271 
0272 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
0273                     struct snd_ctl_elem_value *ucontrol)
0274 {
0275     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0276     unsigned int val;
0277     int change = 0;
0278 
0279     val = ucontrol->value.enumerated.item[0] ;
0280     if (val > 1)
0281         return -EINVAL;
0282     change = (emu->capture_mic_line_in != val);
0283     if (change) {
0284         emu->capture_mic_line_in = val;
0285         ca0106_set_capture_mic_line_in(emu);
0286     }
0287         return change;
0288 }
0289 
0290 static const struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
0291 {
0292     .iface =    SNDRV_CTL_ELEM_IFACE_MIXER,
0293     .name =     "Shared Mic/Line in Capture Switch",
0294     .info =     snd_ca0106_capture_mic_line_in_info,
0295     .get =      snd_ca0106_capture_mic_line_in_get,
0296     .put =      snd_ca0106_capture_mic_line_in_put
0297 };
0298 
0299 static const struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out =
0300 {
0301     .iface =    SNDRV_CTL_ELEM_IFACE_MIXER,
0302     .name =     "Shared Line in/Side out Capture Switch",
0303     .info =     snd_ca0106_capture_line_in_side_out_info,
0304     .get =      snd_ca0106_capture_mic_line_in_get,
0305     .put =      snd_ca0106_capture_mic_line_in_put
0306 };
0307 
0308 
0309 static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
0310                  struct snd_ctl_elem_info *uinfo)
0311 {
0312     uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
0313     uinfo->count = 1;
0314     return 0;
0315 }
0316 
0317 static void decode_spdif_bits(unsigned char *status, unsigned int bits)
0318 {
0319     status[0] = (bits >> 0) & 0xff;
0320     status[1] = (bits >> 8) & 0xff;
0321     status[2] = (bits >> 16) & 0xff;
0322     status[3] = (bits >> 24) & 0xff;
0323 }
0324 
0325 static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
0326                                  struct snd_ctl_elem_value *ucontrol)
0327 {
0328     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0329     unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
0330 
0331     decode_spdif_bits(ucontrol->value.iec958.status,
0332               emu->spdif_bits[idx]);
0333         return 0;
0334 }
0335 
0336 static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
0337                                  struct snd_ctl_elem_value *ucontrol)
0338 {
0339     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0340     unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
0341 
0342     decode_spdif_bits(ucontrol->value.iec958.status,
0343               emu->spdif_str_bits[idx]);
0344         return 0;
0345 }
0346 
0347 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
0348                       struct snd_ctl_elem_value *ucontrol)
0349 {
0350     ucontrol->value.iec958.status[0] = 0xff;
0351     ucontrol->value.iec958.status[1] = 0xff;
0352     ucontrol->value.iec958.status[2] = 0xff;
0353     ucontrol->value.iec958.status[3] = 0xff;
0354         return 0;
0355 }
0356 
0357 static unsigned int encode_spdif_bits(unsigned char *status)
0358 {
0359     return ((unsigned int)status[0] << 0) |
0360         ((unsigned int)status[1] << 8) |
0361         ((unsigned int)status[2] << 16) |
0362         ((unsigned int)status[3] << 24);
0363 }
0364 
0365 static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
0366                                  struct snd_ctl_elem_value *ucontrol)
0367 {
0368     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0369     unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
0370     unsigned int val;
0371 
0372     val = encode_spdif_bits(ucontrol->value.iec958.status);
0373     if (val != emu->spdif_bits[idx]) {
0374         emu->spdif_bits[idx] = val;
0375         /* FIXME: this isn't safe, but needed to keep the compatibility
0376          * with older alsa-lib config
0377          */
0378         emu->spdif_str_bits[idx] = val;
0379         ca0106_set_spdif_bits(emu, idx);
0380         return 1;
0381     }
0382     return 0;
0383 }
0384 
0385 static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
0386                                  struct snd_ctl_elem_value *ucontrol)
0387 {
0388     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0389     unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
0390     unsigned int val;
0391 
0392     val = encode_spdif_bits(ucontrol->value.iec958.status);
0393     if (val != emu->spdif_str_bits[idx]) {
0394         emu->spdif_str_bits[idx] = val;
0395         ca0106_set_spdif_bits(emu, idx);
0396         return 1;
0397     }
0398         return 0;
0399 }
0400 
0401 static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
0402                   struct snd_ctl_elem_info *uinfo)
0403 {
0404         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0405         uinfo->count = 2;
0406         uinfo->value.integer.min = 0;
0407         uinfo->value.integer.max = 255;
0408         return 0;
0409 }
0410 
0411 static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
0412                  struct snd_ctl_elem_value *ucontrol)
0413 {
0414         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0415         unsigned int value;
0416     int channel_id, reg;
0417 
0418     channel_id = (kcontrol->private_value >> 8) & 0xff;
0419     reg = kcontrol->private_value & 0xff;
0420 
0421         value = snd_ca0106_ptr_read(emu, reg, channel_id);
0422         ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
0423         ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
0424         return 0;
0425 }
0426 
0427 static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
0428                  struct snd_ctl_elem_value *ucontrol)
0429 {
0430         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0431         unsigned int oval, nval;
0432     int channel_id, reg;
0433 
0434     channel_id = (kcontrol->private_value >> 8) & 0xff;
0435     reg = kcontrol->private_value & 0xff;
0436 
0437     oval = snd_ca0106_ptr_read(emu, reg, channel_id);
0438     nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
0439         ((0xff - ucontrol->value.integer.value[1]) << 16);
0440         nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
0441         ((0xff - ucontrol->value.integer.value[1]) );
0442     if (oval == nval)
0443         return 0;
0444     snd_ca0106_ptr_write(emu, reg, channel_id, nval);
0445     return 1;
0446 }
0447 
0448 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
0449                   struct snd_ctl_elem_info *uinfo)
0450 {
0451         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0452         uinfo->count = 2;
0453         uinfo->value.integer.min = 0;
0454         uinfo->value.integer.max = 255;
0455         return 0;
0456 }
0457 
0458 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
0459                  struct snd_ctl_elem_value *ucontrol)
0460 {
0461         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0462     int source_id;
0463 
0464     source_id = kcontrol->private_value;
0465 
0466         ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
0467         ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
0468         return 0;
0469 }
0470 
0471 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
0472                  struct snd_ctl_elem_value *ucontrol)
0473 {
0474         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0475         unsigned int ogain;
0476         unsigned int ngain;
0477     int source_id;
0478     int change = 0;
0479 
0480     source_id = kcontrol->private_value;
0481     ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
0482     ngain = ucontrol->value.integer.value[0];
0483     if (ngain > 0xff)
0484         return -EINVAL;
0485     if (ogain != ngain) {
0486         if (emu->i2c_capture_source == source_id)
0487             snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
0488         emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
0489         change = 1;
0490     }
0491     ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
0492     ngain = ucontrol->value.integer.value[1];
0493     if (ngain > 0xff)
0494         return -EINVAL;
0495     if (ogain != ngain) {
0496         if (emu->i2c_capture_source == source_id)
0497             snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
0498         emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
0499         change = 1;
0500     }
0501 
0502     return change;
0503 }
0504 
0505 #define spi_mute_info   snd_ctl_boolean_mono_info
0506 
0507 static int spi_mute_get(struct snd_kcontrol *kcontrol,
0508             struct snd_ctl_elem_value *ucontrol)
0509 {
0510     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0511     unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
0512     unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
0513 
0514     ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
0515     return 0;
0516 }
0517 
0518 static int spi_mute_put(struct snd_kcontrol *kcontrol,
0519             struct snd_ctl_elem_value *ucontrol)
0520 {
0521     struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
0522     unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
0523     unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
0524     int ret;
0525 
0526     ret = emu->spi_dac_reg[reg] & bit;
0527     if (ucontrol->value.integer.value[0]) {
0528         if (!ret)   /* bit already cleared, do nothing */
0529             return 0;
0530         emu->spi_dac_reg[reg] &= ~bit;
0531     } else {
0532         if (ret)    /* bit already set, do nothing */
0533             return 0;
0534         emu->spi_dac_reg[reg] |= bit;
0535     }
0536 
0537     ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
0538     return ret ? -EINVAL : 1;
0539 }
0540 
0541 #define CA_VOLUME(xname,chid,reg) \
0542 {                               \
0543     .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0544     .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |     \
0545               SNDRV_CTL_ELEM_ACCESS_TLV_READ,       \
0546     .info =  snd_ca0106_volume_info,            \
0547     .get =   snd_ca0106_volume_get,             \
0548     .put =   snd_ca0106_volume_put,             \
0549     .tlv = { .p = snd_ca0106_db_scale1 },           \
0550     .private_value = ((chid) << 8) | (reg)          \
0551 }
0552 
0553 static const struct snd_kcontrol_new snd_ca0106_volume_ctls[] = {
0554     CA_VOLUME("Analog Front Playback Volume",
0555           CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
0556         CA_VOLUME("Analog Rear Playback Volume",
0557           CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
0558     CA_VOLUME("Analog Center/LFE Playback Volume",
0559           CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
0560         CA_VOLUME("Analog Side Playback Volume",
0561           CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
0562 
0563         CA_VOLUME("IEC958 Front Playback Volume",
0564           CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
0565     CA_VOLUME("IEC958 Rear Playback Volume",
0566           CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
0567     CA_VOLUME("IEC958 Center/LFE Playback Volume",
0568           CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
0569     CA_VOLUME("IEC958 Unknown Playback Volume",
0570           CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
0571 
0572         CA_VOLUME("CAPTURE feedback Playback Volume",
0573           1, CAPTURE_CONTROL),
0574 
0575     {
0576         .access =   SNDRV_CTL_ELEM_ACCESS_READ,
0577         .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
0578         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
0579         .count =    4,
0580         .info =         snd_ca0106_spdif_info,
0581         .get =          snd_ca0106_spdif_get_mask
0582     },
0583     {
0584         .iface =    SNDRV_CTL_ELEM_IFACE_MIXER,
0585         .name =     "IEC958 Playback Switch",
0586         .info =     snd_ca0106_shared_spdif_info,
0587         .get =      snd_ca0106_shared_spdif_get,
0588         .put =      snd_ca0106_shared_spdif_put
0589     },
0590     {
0591         .iface =    SNDRV_CTL_ELEM_IFACE_MIXER,
0592         .name =     "Digital Source Capture Enum",
0593         .info =     snd_ca0106_capture_source_info,
0594         .get =      snd_ca0106_capture_source_get,
0595         .put =      snd_ca0106_capture_source_put
0596     },
0597     {
0598         .iface =    SNDRV_CTL_ELEM_IFACE_MIXER,
0599         .name =     "Analog Source Capture Enum",
0600         .info =     snd_ca0106_i2c_capture_source_info,
0601         .get =      snd_ca0106_i2c_capture_source_get,
0602         .put =      snd_ca0106_i2c_capture_source_put
0603     },
0604     {
0605         .iface =    SNDRV_CTL_ELEM_IFACE_PCM,
0606         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
0607         .count =    4,
0608         .info =         snd_ca0106_spdif_info,
0609         .get =          snd_ca0106_spdif_get_default,
0610         .put =          snd_ca0106_spdif_put_default
0611     },
0612     {
0613         .iface =    SNDRV_CTL_ELEM_IFACE_PCM,
0614         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
0615         .count =    4,
0616         .info =         snd_ca0106_spdif_info,
0617         .get =          snd_ca0106_spdif_get_stream,
0618         .put =          snd_ca0106_spdif_put_stream
0619     },
0620 };
0621 
0622 #define I2C_VOLUME(xname,chid) \
0623 {                               \
0624     .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0625     .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |     \
0626               SNDRV_CTL_ELEM_ACCESS_TLV_READ,       \
0627     .info =  snd_ca0106_i2c_volume_info,            \
0628     .get =   snd_ca0106_i2c_volume_get,         \
0629     .put =   snd_ca0106_i2c_volume_put,         \
0630     .tlv = { .p = snd_ca0106_db_scale2 },           \
0631     .private_value = chid                   \
0632 }
0633 
0634 static const struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] = {
0635         I2C_VOLUME("Phone Capture Volume", 0),
0636         I2C_VOLUME("Mic Capture Volume", 1),
0637         I2C_VOLUME("Line in Capture Volume", 2),
0638         I2C_VOLUME("Aux Capture Volume", 3),
0639 };
0640 
0641 static const int spi_dmute_reg[] = {
0642     SPI_DMUTE0_REG,
0643     SPI_DMUTE1_REG,
0644     SPI_DMUTE2_REG,
0645     0,
0646     SPI_DMUTE4_REG,
0647 };
0648 static const int spi_dmute_bit[] = {
0649     SPI_DMUTE0_BIT,
0650     SPI_DMUTE1_BIT,
0651     SPI_DMUTE2_BIT,
0652     0,
0653     SPI_DMUTE4_BIT,
0654 };
0655 
0656 static struct snd_kcontrol_new
0657 snd_ca0106_volume_spi_dac_ctl(const struct snd_ca0106_details *details,
0658                   int channel_id)
0659 {
0660     struct snd_kcontrol_new spi_switch = {0};
0661     int reg, bit;
0662     int dac_id;
0663 
0664     spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0665     spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
0666     spi_switch.info = spi_mute_info;
0667     spi_switch.get = spi_mute_get;
0668     spi_switch.put = spi_mute_put;
0669 
0670     switch (channel_id) {
0671     case PCM_FRONT_CHANNEL:
0672         spi_switch.name = "Analog Front Playback Switch";
0673         dac_id = (details->spi_dac & 0xf000) >> (4 * 3);
0674         break;
0675     case PCM_REAR_CHANNEL:
0676         spi_switch.name = "Analog Rear Playback Switch";
0677         dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
0678         break;
0679     case PCM_CENTER_LFE_CHANNEL:
0680         spi_switch.name = "Analog Center/LFE Playback Switch";
0681         dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
0682         break;
0683     case PCM_UNKNOWN_CHANNEL:
0684         spi_switch.name = "Analog Side Playback Switch";
0685         dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
0686         break;
0687     default:
0688         /* Unused channel */
0689         spi_switch.name = NULL;
0690         dac_id = 0;
0691     }
0692     reg = spi_dmute_reg[dac_id];
0693     bit = spi_dmute_bit[dac_id];
0694 
0695     spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
0696 
0697     return spi_switch;
0698 }
0699 
0700 static int remove_ctl(struct snd_card *card, const char *name)
0701 {
0702     struct snd_ctl_elem_id id;
0703     memset(&id, 0, sizeof(id));
0704     strcpy(id.name, name);
0705     id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0706     return snd_ctl_remove_id(card, &id);
0707 }
0708 
0709 static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
0710 {
0711     struct snd_ctl_elem_id sid;
0712     memset(&sid, 0, sizeof(sid));
0713     /* FIXME: strcpy is bad. */
0714     strcpy(sid.name, name);
0715     sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0716     return snd_ctl_find_id(card, &sid);
0717 }
0718 
0719 static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
0720 {
0721     struct snd_kcontrol *kctl = ctl_find(card, src);
0722     if (kctl) {
0723         strcpy(kctl->id.name, dst);
0724         return 0;
0725     }
0726     return -ENOENT;
0727 }
0728 
0729 #define ADD_CTLS(emu, ctls)                     \
0730     do {                                \
0731         int i, _err;                        \
0732         for (i = 0; i < ARRAY_SIZE(ctls); i++) {        \
0733             _err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
0734             if (_err < 0)                   \
0735                 return _err;                \
0736         }                           \
0737     } while (0)
0738 
0739 static
0740 DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
0741 
0742 static const char * const follower_vols[] = {
0743     "Analog Front Playback Volume",
0744         "Analog Rear Playback Volume",
0745     "Analog Center/LFE Playback Volume",
0746         "Analog Side Playback Volume",
0747         "IEC958 Front Playback Volume",
0748     "IEC958 Rear Playback Volume",
0749     "IEC958 Center/LFE Playback Volume",
0750     "IEC958 Unknown Playback Volume",
0751         "CAPTURE feedback Playback Volume",
0752     NULL
0753 };
0754 
0755 static const char * const follower_sws[] = {
0756     "Analog Front Playback Switch",
0757     "Analog Rear Playback Switch",
0758     "Analog Center/LFE Playback Switch",
0759     "Analog Side Playback Switch",
0760     "IEC958 Playback Switch",
0761     NULL
0762 };
0763 
0764 static void add_followers(struct snd_card *card,
0765               struct snd_kcontrol *master, const char * const *list)
0766 {
0767     for (; *list; list++) {
0768         struct snd_kcontrol *follower = ctl_find(card, *list);
0769         if (follower)
0770             snd_ctl_add_follower(master, follower);
0771     }
0772 }
0773 
0774 int snd_ca0106_mixer(struct snd_ca0106 *emu)
0775 {
0776     int err;
0777         struct snd_card *card = emu->card;
0778     const char * const *c;
0779     struct snd_kcontrol *vmaster;
0780     static const char * const ca0106_remove_ctls[] = {
0781         "Master Mono Playback Switch",
0782         "Master Mono Playback Volume",
0783         "3D Control - Switch",
0784         "3D Control Sigmatel - Depth",
0785         "PCM Playback Switch",
0786         "PCM Playback Volume",
0787         "CD Playback Switch",
0788         "CD Playback Volume",
0789         "Phone Playback Switch",
0790         "Phone Playback Volume",
0791         "Video Playback Switch",
0792         "Video Playback Volume",
0793         "Beep Playback Switch",
0794         "Beep Playback Volume",
0795         "Mono Output Select",
0796         "Capture Source",
0797         "Capture Switch",
0798         "Capture Volume",
0799         "External Amplifier",
0800         "Sigmatel 4-Speaker Stereo Playback Switch",
0801         "Surround Phase Inversion Playback Switch",
0802         NULL
0803     };
0804     static const char * const ca0106_rename_ctls[] = {
0805         "Master Playback Switch", "Capture Switch",
0806         "Master Playback Volume", "Capture Volume",
0807         "Line Playback Switch", "AC97 Line Capture Switch",
0808         "Line Playback Volume", "AC97 Line Capture Volume",
0809         "Aux Playback Switch", "AC97 Aux Capture Switch",
0810         "Aux Playback Volume", "AC97 Aux Capture Volume",
0811         "Mic Playback Switch", "AC97 Mic Capture Switch",
0812         "Mic Playback Volume", "AC97 Mic Capture Volume",
0813         "Mic Select", "AC97 Mic Select",
0814         "Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
0815         NULL
0816     };
0817 #if 1
0818     for (c = ca0106_remove_ctls; *c; c++)
0819         remove_ctl(card, *c);
0820     for (c = ca0106_rename_ctls; *c; c += 2)
0821         rename_ctl(card, c[0], c[1]);
0822 #endif
0823 
0824     ADD_CTLS(emu, snd_ca0106_volume_ctls);
0825     if (emu->details->i2c_adc == 1) {
0826         ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
0827         if (emu->details->gpio_type == 1)
0828             err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
0829         else  /* gpio_type == 2 */
0830             err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
0831         if (err < 0)
0832             return err;
0833     }
0834     if (emu->details->spi_dac) {
0835         int i;
0836         for (i = 0;; i++) {
0837             struct snd_kcontrol_new ctl;
0838             ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
0839             if (!ctl.name)
0840                 break;
0841             err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
0842             if (err < 0)
0843                 return err;
0844         }
0845     }
0846 
0847     /* Create virtual master controls */
0848     vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
0849                           snd_ca0106_master_db_scale);
0850     if (!vmaster)
0851         return -ENOMEM;
0852     err = snd_ctl_add(card, vmaster);
0853     if (err < 0)
0854         return err;
0855     add_followers(card, vmaster, follower_vols);
0856 
0857     if (emu->details->spi_dac) {
0858         vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
0859                               NULL);
0860         if (!vmaster)
0861             return -ENOMEM;
0862         err = snd_ctl_add(card, vmaster);
0863         if (err < 0)
0864             return err;
0865         add_followers(card, vmaster, follower_sws);
0866     }
0867 
0868     strcpy(card->mixername, "CA0106");
0869         return 0;
0870 }
0871 
0872 #ifdef CONFIG_PM_SLEEP
0873 struct ca0106_vol_tbl {
0874     unsigned int channel_id;
0875     unsigned int reg;
0876 };
0877 
0878 static const struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
0879     { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
0880     { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
0881     { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
0882     { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
0883     { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
0884     { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
0885     { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
0886     { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
0887     { 1, CAPTURE_CONTROL },
0888 };
0889 
0890 void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
0891 {
0892     int i;
0893 
0894     /* save volumes */
0895     for (i = 0; i < NUM_SAVED_VOLUMES; i++)
0896         chip->saved_vol[i] =
0897             snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
0898                         saved_volumes[i].channel_id);
0899 }
0900 
0901 void snd_ca0106_mixer_resume(struct snd_ca0106  *chip)
0902 {
0903     int i;
0904 
0905     for (i = 0; i < NUM_SAVED_VOLUMES; i++)
0906         snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
0907                      saved_volumes[i].channel_id,
0908                      chip->saved_vol[i]);
0909 
0910     ca0106_spdif_enable(chip);
0911     ca0106_set_capture_source(chip);
0912     ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
0913     for (i = 0; i < 4; i++)
0914         ca0106_set_spdif_bits(chip, i);
0915     if (chip->details->i2c_adc)
0916         ca0106_set_capture_mic_line_in(chip);
0917 }
0918 #endif /* CONFIG_PM_SLEEP */