0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
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
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
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);
0103 ngain = emu->i2c_capture_volume[val][0];
0104 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0];
0105 if (force || ngain != ogain)
0106 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
0107 ngain = emu->i2c_capture_volume[val][1];
0108 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1];
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);
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
0122 tmp = inl(emu->port + CA0106_GPIO) & ~0x400;
0123 tmp = tmp | 0x400;
0124 outl(tmp, emu->port + CA0106_GPIO);
0125
0126 } else {
0127
0128 tmp = inl(emu->port + CA0106_GPIO) & ~0x400;
0129 outl(tmp, emu->port + CA0106_GPIO);
0130
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
0234
0235
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
0376
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);
0423 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff);
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];
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];
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)
0529 return 0;
0530 emu->spi_dac_reg[reg] &= ~bit;
0531 } else {
0532 if (ret)
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
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
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
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
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
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