0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/time.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/init.h>
0013 #include <linux/mutex.h>
0014
0015 #include <sound/core.h>
0016 #include "mixart.h"
0017 #include "mixart_core.h"
0018 #include "mixart_hwdep.h"
0019 #include <sound/control.h>
0020 #include <sound/tlv.h>
0021 #include "mixart_mixer.h"
0022
0023 static const u32 mixart_analog_level[256] = {
0024 0xc2c00000,
0025 0xc2bf0000,
0026 0xc2be0000,
0027 0xc2bd0000,
0028 0xc2bc0000,
0029 0xc2bb0000,
0030 0xc2ba0000,
0031 0xc2b90000,
0032 0xc2b80000,
0033 0xc2b70000,
0034 0xc2b60000,
0035 0xc2b50000,
0036 0xc2b40000,
0037 0xc2b30000,
0038 0xc2b20000,
0039 0xc2b10000,
0040 0xc2b00000,
0041 0xc2af0000,
0042 0xc2ae0000,
0043 0xc2ad0000,
0044 0xc2ac0000,
0045 0xc2ab0000,
0046 0xc2aa0000,
0047 0xc2a90000,
0048 0xc2a80000,
0049 0xc2a70000,
0050 0xc2a60000,
0051 0xc2a50000,
0052 0xc2a40000,
0053 0xc2a30000,
0054 0xc2a20000,
0055 0xc2a10000,
0056 0xc2a00000,
0057 0xc29f0000,
0058 0xc29e0000,
0059 0xc29d0000,
0060 0xc29c0000,
0061 0xc29b0000,
0062 0xc29a0000,
0063 0xc2990000,
0064 0xc2980000,
0065 0xc2970000,
0066 0xc2960000,
0067 0xc2950000,
0068 0xc2940000,
0069 0xc2930000,
0070 0xc2920000,
0071 0xc2910000,
0072 0xc2900000,
0073 0xc28f0000,
0074 0xc28e0000,
0075 0xc28d0000,
0076 0xc28c0000,
0077 0xc28b0000,
0078 0xc28a0000,
0079 0xc2890000,
0080 0xc2880000,
0081 0xc2870000,
0082 0xc2860000,
0083 0xc2850000,
0084 0xc2840000,
0085 0xc2830000,
0086 0xc2820000,
0087 0xc2810000,
0088 0xc2800000,
0089 0xc27e0000,
0090 0xc27c0000,
0091 0xc27a0000,
0092 0xc2780000,
0093 0xc2760000,
0094 0xc2740000,
0095 0xc2720000,
0096 0xc2700000,
0097 0xc26e0000,
0098 0xc26c0000,
0099 0xc26a0000,
0100 0xc2680000,
0101 0xc2660000,
0102 0xc2640000,
0103 0xc2620000,
0104 0xc2600000,
0105 0xc25e0000,
0106 0xc25c0000,
0107 0xc25a0000,
0108 0xc2580000,
0109 0xc2560000,
0110 0xc2540000,
0111 0xc2520000,
0112 0xc2500000,
0113 0xc24e0000,
0114 0xc24c0000,
0115 0xc24a0000,
0116 0xc2480000,
0117 0xc2460000,
0118 0xc2440000,
0119 0xc2420000,
0120 0xc2400000,
0121 0xc23e0000,
0122 0xc23c0000,
0123 0xc23a0000,
0124 0xc2380000,
0125 0xc2360000,
0126 0xc2340000,
0127 0xc2320000,
0128 0xc2300000,
0129 0xc22e0000,
0130 0xc22c0000,
0131 0xc22a0000,
0132 0xc2280000,
0133 0xc2260000,
0134 0xc2240000,
0135 0xc2220000,
0136 0xc2200000,
0137 0xc21e0000,
0138 0xc21c0000,
0139 0xc21a0000,
0140 0xc2180000,
0141 0xc2160000,
0142 0xc2140000,
0143 0xc2120000,
0144 0xc2100000,
0145 0xc20e0000,
0146 0xc20c0000,
0147 0xc20a0000,
0148 0xc2080000,
0149 0xc2060000,
0150 0xc2040000,
0151 0xc2020000,
0152 0xc2000000,
0153 0xc1fc0000,
0154 0xc1f80000,
0155 0xc1f40000,
0156 0xc1f00000,
0157 0xc1ec0000,
0158 0xc1e80000,
0159 0xc1e40000,
0160 0xc1e00000,
0161 0xc1dc0000,
0162 0xc1d80000,
0163 0xc1d40000,
0164 0xc1d00000,
0165 0xc1cc0000,
0166 0xc1c80000,
0167 0xc1c40000,
0168 0xc1c00000,
0169 0xc1bc0000,
0170 0xc1b80000,
0171 0xc1b40000,
0172 0xc1b00000,
0173 0xc1ac0000,
0174 0xc1a80000,
0175 0xc1a40000,
0176 0xc1a00000,
0177 0xc19c0000,
0178 0xc1980000,
0179 0xc1940000,
0180 0xc1900000,
0181 0xc18c0000,
0182 0xc1880000,
0183 0xc1840000,
0184 0xc1800000,
0185 0xc1780000,
0186 0xc1700000,
0187 0xc1680000,
0188 0xc1600000,
0189 0xc1580000,
0190 0xc1500000,
0191 0xc1480000,
0192 0xc1400000,
0193 0xc1380000,
0194 0xc1300000,
0195 0xc1280000,
0196 0xc1200000,
0197 0xc1180000,
0198 0xc1100000,
0199 0xc1080000,
0200 0xc1000000,
0201 0xc0f00000,
0202 0xc0e00000,
0203 0xc0d00000,
0204 0xc0c00000,
0205 0xc0b00000,
0206 0xc0a00000,
0207 0xc0900000,
0208 0xc0800000,
0209 0xc0600000,
0210 0xc0400000,
0211 0xc0200000,
0212 0xc0000000,
0213 0xbfc00000,
0214 0xbf800000,
0215 0xbf000000,
0216 0x00000000,
0217 0x3f000000,
0218 0x3f800000,
0219 0x3fc00000,
0220 0x40000000,
0221 0x40200000,
0222 0x40400000,
0223 0x40600000,
0224 0x40800000,
0225 0x40900000,
0226 0x40a00000,
0227 0x40b00000,
0228 0x40c00000,
0229 0x40d00000,
0230 0x40e00000,
0231 0x40f00000,
0232 0x41000000,
0233 0x41080000,
0234 0x41100000,
0235 0x41180000,
0236 0x41200000,
0237 0x41280000,
0238 0x41300000,
0239 0x41380000,
0240 0x41400000,
0241 0x41480000,
0242 0x41500000,
0243 0x41580000,
0244 0x41600000,
0245 0x41680000,
0246 0x41700000,
0247 0x41780000,
0248 0x41800000,
0249 0x41840000,
0250 0x41880000,
0251 0x418c0000,
0252 0x41900000,
0253 0x41940000,
0254 0x41980000,
0255 0x419c0000,
0256 0x41a00000,
0257 0x41a40000,
0258 0x41a80000,
0259 0x41ac0000,
0260 0x41b00000,
0261 0x41b40000,
0262 0x41b80000,
0263 0x41bc0000,
0264 0x41c00000,
0265 0x41c40000,
0266 0x41c80000,
0267 0x41cc0000,
0268 0x41d00000,
0269 0x41d40000,
0270 0x41d80000,
0271 0x41dc0000,
0272 0x41e00000,
0273 0x41e40000,
0274 0x41e80000,
0275 0x41ec0000,
0276 0x41f00000,
0277 0x41f40000,
0278 0x41f80000,
0279 0x41fc0000,
0280 };
0281
0282 #define MIXART_ANALOG_CAPTURE_LEVEL_MIN 0
0283 #define MIXART_ANALOG_CAPTURE_LEVEL_MAX 255
0284 #define MIXART_ANALOG_CAPTURE_ZERO_LEVEL 176
0285
0286 #define MIXART_ANALOG_PLAYBACK_LEVEL_MIN 0
0287 #define MIXART_ANALOG_PLAYBACK_LEVEL_MAX 192
0288 #define MIXART_ANALOG_PLAYBACK_ZERO_LEVEL 189
0289
0290 static int mixart_update_analog_audio_level(struct snd_mixart* chip, int is_capture)
0291 {
0292 int i, err;
0293 struct mixart_msg request;
0294 struct mixart_io_level io_level;
0295 struct mixart_return_uid resp;
0296
0297 memset(&io_level, 0, sizeof(io_level));
0298 io_level.channel = -1;
0299
0300 for(i=0; i<2; i++) {
0301 if(is_capture) {
0302 io_level.level[i].analog_level = mixart_analog_level[chip->analog_capture_volume[i]];
0303 } else {
0304 if(chip->analog_playback_active[i])
0305 io_level.level[i].analog_level = mixart_analog_level[chip->analog_playback_volume[i]];
0306 else
0307 io_level.level[i].analog_level = mixart_analog_level[MIXART_ANALOG_PLAYBACK_LEVEL_MIN];
0308 }
0309 }
0310
0311 if(is_capture) request.uid = chip->uid_in_analog_physio;
0312 else request.uid = chip->uid_out_analog_physio;
0313 request.message_id = MSG_PHYSICALIO_SET_LEVEL;
0314 request.data = &io_level;
0315 request.size = sizeof(io_level);
0316
0317 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
0318 if((err<0) || (resp.error_code)) {
0319 dev_dbg(chip->card->dev,
0320 "error MSG_PHYSICALIO_SET_LEVEL card(%d) is_capture(%d) error_code(%x)\n",
0321 chip->chip_idx, is_capture, resp.error_code);
0322 return -EINVAL;
0323 }
0324 return 0;
0325 }
0326
0327
0328
0329
0330 static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0331 {
0332 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0333 uinfo->count = 2;
0334 if(kcontrol->private_value == 0) {
0335 uinfo->value.integer.min = MIXART_ANALOG_PLAYBACK_LEVEL_MIN;
0336 uinfo->value.integer.max = MIXART_ANALOG_PLAYBACK_LEVEL_MAX;
0337 } else {
0338 uinfo->value.integer.min = MIXART_ANALOG_CAPTURE_LEVEL_MIN;
0339 uinfo->value.integer.max = MIXART_ANALOG_CAPTURE_LEVEL_MAX;
0340 }
0341 return 0;
0342 }
0343
0344 static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0345 {
0346 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0347 mutex_lock(&chip->mgr->mixer_mutex);
0348 if(kcontrol->private_value == 0) {
0349 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
0350 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
0351 } else {
0352 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
0353 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
0354 }
0355 mutex_unlock(&chip->mgr->mixer_mutex);
0356 return 0;
0357 }
0358
0359 static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0360 {
0361 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0362 int changed = 0;
0363 int is_capture, i;
0364
0365 mutex_lock(&chip->mgr->mixer_mutex);
0366 is_capture = (kcontrol->private_value != 0);
0367 for (i = 0; i < 2; i++) {
0368 int new_volume = ucontrol->value.integer.value[i];
0369 int *stored_volume = is_capture ?
0370 &chip->analog_capture_volume[i] :
0371 &chip->analog_playback_volume[i];
0372 if (is_capture) {
0373 if (new_volume < MIXART_ANALOG_CAPTURE_LEVEL_MIN ||
0374 new_volume > MIXART_ANALOG_CAPTURE_LEVEL_MAX)
0375 continue;
0376 } else {
0377 if (new_volume < MIXART_ANALOG_PLAYBACK_LEVEL_MIN ||
0378 new_volume > MIXART_ANALOG_PLAYBACK_LEVEL_MAX)
0379 continue;
0380 }
0381 if (*stored_volume != new_volume) {
0382 *stored_volume = new_volume;
0383 changed = 1;
0384 }
0385 }
0386 if (changed)
0387 mixart_update_analog_audio_level(chip, is_capture);
0388 mutex_unlock(&chip->mgr->mixer_mutex);
0389 return changed;
0390 }
0391
0392 static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0);
0393
0394 static const struct snd_kcontrol_new mixart_control_analog_level = {
0395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0396 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0397 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0398
0399 .info = mixart_analog_vol_info,
0400 .get = mixart_analog_vol_get,
0401 .put = mixart_analog_vol_put,
0402 .tlv = { .p = db_scale_analog },
0403 };
0404
0405
0406 #define mixart_sw_info snd_ctl_boolean_stereo_info
0407
0408 static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0409 {
0410 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0411
0412 mutex_lock(&chip->mgr->mixer_mutex);
0413 ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
0414 ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
0415 mutex_unlock(&chip->mgr->mixer_mutex);
0416 return 0;
0417 }
0418
0419 static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0420 {
0421 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0422 int i, changed = 0;
0423 mutex_lock(&chip->mgr->mixer_mutex);
0424 for (i = 0; i < 2; i++) {
0425 if (chip->analog_playback_active[i] !=
0426 ucontrol->value.integer.value[i]) {
0427 chip->analog_playback_active[i] =
0428 !!ucontrol->value.integer.value[i];
0429 changed = 1;
0430 }
0431 }
0432 if (changed)
0433 mixart_update_analog_audio_level(chip, 0);
0434 mutex_unlock(&chip->mgr->mixer_mutex);
0435 return changed;
0436 }
0437
0438 static const struct snd_kcontrol_new mixart_control_output_switch = {
0439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0440 .name = "Master Playback Switch",
0441 .info = mixart_sw_info,
0442 .get = mixart_audio_sw_get,
0443 .put = mixart_audio_sw_put
0444 };
0445
0446 static const u32 mixart_digital_level[256] = {
0447 0x00000000,
0448 0x366e1c7a,
0449 0x367c3860,
0450 0x36859525,
0451 0x368d7f74,
0452 0x3695e1d4,
0453 0x369ec362,
0454 0x36a82ba8,
0455 0x36b222a0,
0456 0x36bcb0c1,
0457 0x36c7defd,
0458 0x36d3b6d3,
0459 0x36e0424e,
0460 0x36ed8c14,
0461 0x36fb9f6c,
0462 0x37054423,
0463 0x370d29a5,
0464 0x371586f0,
0465 0x371e631b,
0466 0x3727c5ac,
0467 0x3731b69a,
0468 0x373c3e53,
0469 0x374765c8,
0470 0x3753366f,
0471 0x375fba4f,
0472 0x376cfc07,
0473 0x377b06d5,
0474 0x3784f352,
0475 0x378cd40b,
0476 0x37952c42,
0477 0x379e030e,
0478 0x37a75fef,
0479 0x37b14ad5,
0480 0x37bbcc2c,
0481 0x37c6ecdd,
0482 0x37d2b65a,
0483 0x37df32a3,
0484 0x37ec6c50,
0485 0x37fa6e9b,
0486 0x3804a2b3,
0487 0x380c7ea4,
0488 0x3814d1cc,
0489 0x381da33c,
0490 0x3826fa6f,
0491 0x3830df51,
0492 0x383b5a49,
0493 0x3846743b,
0494 0x38523692,
0495 0x385eab48,
0496 0x386bdcf1,
0497 0x3879d6bc,
0498 0x38845244,
0499 0x388c2971,
0500 0x3894778d,
0501 0x389d43a4,
0502 0x38a6952c,
0503 0x38b0740f,
0504 0x38bae8ac,
0505 0x38c5fbe2,
0506 0x38d1b717,
0507 0x38de2440,
0508 0x38eb4de8,
0509 0x38f93f3a,
0510 0x39040206,
0511 0x390bd472,
0512 0x39141d84,
0513 0x391ce445,
0514 0x39263027,
0515 0x3930090d,
0516 0x393a7753,
0517 0x394583d2,
0518 0x395137ea,
0519 0x395d9d8a,
0520 0x396abf37,
0521 0x3978a814,
0522 0x3983b1f8,
0523 0x398b7fa6,
0524 0x3993c3b2,
0525 0x399c8521,
0526 0x39a5cb5f,
0527 0x39af9e4d,
0528 0x39ba063f,
0529 0x39c50c0b,
0530 0x39d0b90a,
0531 0x39dd1726,
0532 0x39ea30db,
0533 0x39f81149,
0534 0x3a03621b,
0535 0x3a0b2b0d,
0536 0x3a136a16,
0537 0x3a1c2636,
0538 0x3a2566d5,
0539 0x3a2f33cd,
0540 0x3a399570,
0541 0x3a44948c,
0542 0x3a503a77,
0543 0x3a5c9112,
0544 0x3a69a2d7,
0545 0x3a777ada,
0546 0x3a83126f,
0547 0x3a8ad6a8,
0548 0x3a9310b1,
0549 0x3a9bc784,
0550 0x3aa50287,
0551 0x3aaec98e,
0552 0x3ab924e5,
0553 0x3ac41d56,
0554 0x3acfbc31,
0555 0x3adc0b51,
0556 0x3ae91528,
0557 0x3af6e4c6,
0558 0x3b02c2f2,
0559 0x3b0a8276,
0560 0x3b12b782,
0561 0x3b1b690d,
0562 0x3b249e76,
0563 0x3b2e5f8f,
0564 0x3b38b49f,
0565 0x3b43a669,
0566 0x3b4f3e37,
0567 0x3b5b85e0,
0568 0x3b6887cf,
0569 0x3b764f0e,
0570 0x3b8273a6,
0571 0x3b8a2e77,
0572 0x3b925e89,
0573 0x3b9b0ace,
0574 0x3ba43aa2,
0575 0x3badf5d1,
0576 0x3bb8449c,
0577 0x3bc32fc3,
0578 0x3bcec08a,
0579 0x3bdb00c0,
0580 0x3be7facc,
0581 0x3bf5b9b0,
0582 0x3c02248a,
0583 0x3c09daac,
0584 0x3c1205c6,
0585 0x3c1aacc8,
0586 0x3c23d70a,
0587 0x3c2d8c52,
0588 0x3c37d4dd,
0589 0x3c42b965,
0590 0x3c4e4329,
0591 0x3c5a7bf1,
0592 0x3c676e1e,
0593 0x3c7524ac,
0594 0x3c81d59f,
0595 0x3c898712,
0596 0x3c91ad39,
0597 0x3c9a4efc,
0598 0x3ca373af,
0599 0x3cad2314,
0600 0x3cb76563,
0601 0x3cc24350,
0602 0x3ccdc614,
0603 0x3cd9f773,
0604 0x3ce6e1c6,
0605 0x3cf49003,
0606 0x3d0186e2,
0607 0x3d0933ac,
0608 0x3d1154e1,
0609 0x3d19f169,
0610 0x3d231090,
0611 0x3d2cba15,
0612 0x3d36f62b,
0613 0x3d41cd81,
0614 0x3d4d494a,
0615 0x3d597345,
0616 0x3d6655c3,
0617 0x3d73fbb4,
0618 0x3d813856,
0619 0x3d88e078,
0620 0x3d90fcbf,
0621 0x3d99940e,
0622 0x3da2adad,
0623 0x3dac5156,
0624 0x3db68738,
0625 0x3dc157fb,
0626 0x3dcccccd,
0627 0x3dd8ef67,
0628 0x3de5ca15,
0629 0x3df367bf,
0630 0x3e00e9f9,
0631 0x3e088d77,
0632 0x3e10a4d3,
0633 0x3e1936ec,
0634 0x3e224b06,
0635 0x3e2be8d7,
0636 0x3e361887,
0637 0x3e40e2bb,
0638 0x3e4c509b,
0639 0x3e586bd9,
0640 0x3e653ebb,
0641 0x3e72d424,
0642 0x3e809bcc,
0643 0x3e883aa8,
0644 0x3e904d1c,
0645 0x3e98da02,
0646 0x3ea1e89b,
0647 0x3eab8097,
0648 0x3eb5aa1a,
0649 0x3ec06dc3,
0650 0x3ecbd4b4,
0651 0x3ed7e89b,
0652 0x3ee4b3b6,
0653 0x3ef240e2,
0654 0x3f004dce,
0655 0x3f07e80b,
0656 0x3f0ff59a,
0657 0x3f187d50,
0658 0x3f21866c,
0659 0x3f2b1896,
0660 0x3f353bef,
0661 0x3f3ff911,
0662 0x3f4b5918,
0663 0x3f5765ac,
0664 0x3f642905,
0665 0x3f71adf9,
0666 0x3f800000,
0667 0x3f8795a0,
0668 0x3f8f9e4d,
0669 0x3f9820d7,
0670 0x3fa12478,
0671 0x3faab0d5,
0672 0x3fb4ce08,
0673 0x3fbf84a6,
0674 0x3fcaddc8,
0675 0x3fd6e30d,
0676 0x3fe39ea9,
0677 0x3ff11b6a,
0678 0x3fff64c1,
0679 0x40074368,
0680 0x400f4735,
0681 0x4017c496,
0682 0x4020c2bf,
0683 0x402a4952,
0684 0x40346063,
0685 0x403f1082,
0686 0x404a62c2,
0687 0x405660bd,
0688 0x406314a0,
0689 0x40708933,
0690 0x407ec9e1,
0691 0x4086f161,
0692 0x408ef052,
0693 0x4097688d,
0694 0x40a06142,
0695 0x40a9e20e,
0696 0x40b3f300,
0697 0x40be9ca5,
0698 0x40c9e807,
0699 0x40d5debc,
0700 0x40e28aeb,
0701 0x40eff755,
0702 0x40fe2f5e,
0703 };
0704
0705 #define MIXART_DIGITAL_LEVEL_MIN 0
0706 #define MIXART_DIGITAL_LEVEL_MAX 255
0707 #define MIXART_DIGITAL_ZERO_LEVEL 219
0708
0709
0710 int mixart_update_playback_stream_level(struct snd_mixart* chip, int is_aes, int idx)
0711 {
0712 int err, i;
0713 int volume[2];
0714 struct mixart_msg request;
0715 struct mixart_set_out_stream_level_req set_level;
0716 u32 status = 0;
0717 struct mixart_pipe *pipe;
0718
0719 memset(&set_level, 0, sizeof(set_level));
0720 set_level.nb_of_stream = 1;
0721 set_level.stream_level.desc.stream_idx = idx;
0722
0723 if(is_aes) {
0724 pipe = &chip->pipe_out_dig;
0725 idx += MIXART_PLAYBACK_STREAMS;
0726 } else {
0727 pipe = &chip->pipe_out_ana;
0728 }
0729
0730
0731 if(pipe->status == PIPE_UNDEFINED)
0732 return 0;
0733
0734 set_level.stream_level.desc.uid_pipe = pipe->group_uid;
0735
0736 for(i=0; i<2; i++) {
0737 if(chip->digital_playback_active[idx][i])
0738 volume[i] = chip->digital_playback_volume[idx][i];
0739 else
0740 volume[i] = MIXART_DIGITAL_LEVEL_MIN;
0741 }
0742
0743 set_level.stream_level.out_level.valid_mask1 = MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO1 | MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO2;
0744 set_level.stream_level.out_level.left_to_out1_level = mixart_digital_level[volume[0]];
0745 set_level.stream_level.out_level.right_to_out2_level = mixart_digital_level[volume[1]];
0746
0747 request.message_id = MSG_STREAM_SET_OUT_STREAM_LEVEL;
0748 request.uid = (struct mixart_uid){0,0};
0749 request.data = &set_level;
0750 request.size = sizeof(set_level);
0751
0752 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
0753 if((err<0) || status) {
0754 dev_dbg(chip->card->dev,
0755 "error MSG_STREAM_SET_OUT_STREAM_LEVEL card(%d) status(%x)\n",
0756 chip->chip_idx, status);
0757 return -EINVAL;
0758 }
0759 return 0;
0760 }
0761
0762 int mixart_update_capture_stream_level(struct snd_mixart* chip, int is_aes)
0763 {
0764 int err, i, idx;
0765 struct mixart_pipe *pipe;
0766 struct mixart_msg request;
0767 struct mixart_set_in_audio_level_req set_level;
0768 u32 status = 0;
0769
0770 if(is_aes) {
0771 idx = 1;
0772 pipe = &chip->pipe_in_dig;
0773 } else {
0774 idx = 0;
0775 pipe = &chip->pipe_in_ana;
0776 }
0777
0778
0779 if(pipe->status == PIPE_UNDEFINED)
0780 return 0;
0781
0782 memset(&set_level, 0, sizeof(set_level));
0783 set_level.audio_count = 2;
0784 set_level.level[0].connector = pipe->uid_left_connector;
0785 set_level.level[1].connector = pipe->uid_right_connector;
0786
0787 for(i=0; i<2; i++) {
0788 set_level.level[i].valid_mask1 = MIXART_AUDIO_LEVEL_DIGITAL_MASK;
0789 set_level.level[i].digital_level = mixart_digital_level[chip->digital_capture_volume[idx][i]];
0790 }
0791
0792 request.message_id = MSG_STREAM_SET_IN_AUDIO_LEVEL;
0793 request.uid = (struct mixart_uid){0,0};
0794 request.data = &set_level;
0795 request.size = sizeof(set_level);
0796
0797 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
0798 if((err<0) || status) {
0799 dev_dbg(chip->card->dev,
0800 "error MSG_STREAM_SET_IN_AUDIO_LEVEL card(%d) status(%x)\n",
0801 chip->chip_idx, status);
0802 return -EINVAL;
0803 }
0804 return 0;
0805 }
0806
0807
0808
0809 static int mixart_digital_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0810 {
0811 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0812 uinfo->count = 2;
0813 uinfo->value.integer.min = MIXART_DIGITAL_LEVEL_MIN;
0814 uinfo->value.integer.max = MIXART_DIGITAL_LEVEL_MAX;
0815 return 0;
0816 }
0817
0818 #define MIXART_VOL_REC_MASK 1
0819 #define MIXART_VOL_AES_MASK 2
0820
0821 static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0822 {
0823 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0824 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
0825 int *stored_volume;
0826 int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
0827 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
0828 mutex_lock(&chip->mgr->mixer_mutex);
0829 if(is_capture) {
0830 if(is_aes) stored_volume = chip->digital_capture_volume[1];
0831 else stored_volume = chip->digital_capture_volume[0];
0832 } else {
0833 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
0834 if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
0835 else stored_volume = chip->digital_playback_volume[idx];
0836 }
0837 ucontrol->value.integer.value[0] = stored_volume[0];
0838 ucontrol->value.integer.value[1] = stored_volume[1];
0839 mutex_unlock(&chip->mgr->mixer_mutex);
0840 return 0;
0841 }
0842
0843 static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0844 {
0845 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0846 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
0847 int changed = 0;
0848 int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
0849 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
0850 int* stored_volume;
0851 int i;
0852 mutex_lock(&chip->mgr->mixer_mutex);
0853 if (is_capture) {
0854 if (is_aes)
0855 stored_volume = chip->digital_capture_volume[1];
0856 else
0857 stored_volume = chip->digital_capture_volume[0];
0858 } else {
0859 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
0860 if (is_aes)
0861 stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
0862 else
0863 stored_volume = chip->digital_playback_volume[idx];
0864 }
0865 for (i = 0; i < 2; i++) {
0866 int vol = ucontrol->value.integer.value[i];
0867 if (vol < MIXART_DIGITAL_LEVEL_MIN ||
0868 vol > MIXART_DIGITAL_LEVEL_MAX)
0869 continue;
0870 if (stored_volume[i] != vol) {
0871 stored_volume[i] = vol;
0872 changed = 1;
0873 }
0874 }
0875 if (changed) {
0876 if (is_capture)
0877 mixart_update_capture_stream_level(chip, is_aes);
0878 else
0879 mixart_update_playback_stream_level(chip, is_aes, idx);
0880 }
0881 mutex_unlock(&chip->mgr->mixer_mutex);
0882 return changed;
0883 }
0884
0885 static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0);
0886
0887 static const struct snd_kcontrol_new snd_mixart_pcm_vol =
0888 {
0889 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0890 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0891 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0892
0893
0894 .info = mixart_digital_vol_info,
0895 .get = mixart_pcm_vol_get,
0896 .put = mixart_pcm_vol_put,
0897 .tlv = { .p = db_scale_digital },
0898 };
0899
0900
0901 static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0902 {
0903 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0904 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
0905 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
0906 mutex_lock(&chip->mgr->mixer_mutex);
0907 if(kcontrol->private_value & MIXART_VOL_AES_MASK)
0908 idx += MIXART_PLAYBACK_STREAMS;
0909 ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
0910 ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
0911 mutex_unlock(&chip->mgr->mixer_mutex);
0912 return 0;
0913 }
0914
0915 static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0916 {
0917 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0918 int changed = 0;
0919 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
0920 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
0921 int i, j;
0922 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
0923 mutex_lock(&chip->mgr->mixer_mutex);
0924 j = idx;
0925 if (is_aes)
0926 j += MIXART_PLAYBACK_STREAMS;
0927 for (i = 0; i < 2; i++) {
0928 if (chip->digital_playback_active[j][i] !=
0929 ucontrol->value.integer.value[i]) {
0930 chip->digital_playback_active[j][i] =
0931 !!ucontrol->value.integer.value[i];
0932 changed = 1;
0933 }
0934 }
0935 if (changed)
0936 mixart_update_playback_stream_level(chip, is_aes, idx);
0937 mutex_unlock(&chip->mgr->mixer_mutex);
0938 return changed;
0939 }
0940
0941 static const struct snd_kcontrol_new mixart_control_pcm_switch = {
0942 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0943
0944 .count = MIXART_PLAYBACK_STREAMS,
0945 .info = mixart_sw_info,
0946 .get = mixart_pcm_sw_get,
0947 .put = mixart_pcm_sw_put
0948 };
0949
0950 static int mixart_update_monitoring(struct snd_mixart* chip, int channel)
0951 {
0952 int err;
0953 struct mixart_msg request;
0954 struct mixart_set_out_audio_level audio_level;
0955 u32 resp = 0;
0956
0957 if(chip->pipe_out_ana.status == PIPE_UNDEFINED)
0958 return -EINVAL;
0959
0960 if(!channel) request.uid = chip->pipe_out_ana.uid_left_connector;
0961 else request.uid = chip->pipe_out_ana.uid_right_connector;
0962 request.message_id = MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL;
0963 request.data = &audio_level;
0964 request.size = sizeof(audio_level);
0965
0966 memset(&audio_level, 0, sizeof(audio_level));
0967 audio_level.valid_mask1 = MIXART_AUDIO_LEVEL_MONITOR_MASK | MIXART_AUDIO_LEVEL_MUTE_M1_MASK;
0968 audio_level.monitor_level = mixart_digital_level[chip->monitoring_volume[channel!=0]];
0969 audio_level.monitor_mute1 = !chip->monitoring_active[channel!=0];
0970
0971 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
0972 if((err<0) || resp) {
0973 dev_dbg(chip->card->dev,
0974 "error MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL card(%d) resp(%x)\n",
0975 chip->chip_idx, resp);
0976 return -EINVAL;
0977 }
0978 return 0;
0979 }
0980
0981
0982
0983
0984
0985 static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0986 {
0987 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0988 mutex_lock(&chip->mgr->mixer_mutex);
0989 ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
0990 ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
0991 mutex_unlock(&chip->mgr->mixer_mutex);
0992 return 0;
0993 }
0994
0995 static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0996 {
0997 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
0998 int changed = 0;
0999 int i;
1000 mutex_lock(&chip->mgr->mixer_mutex);
1001 for (i = 0; i < 2; i++) {
1002 if (chip->monitoring_volume[i] !=
1003 ucontrol->value.integer.value[i]) {
1004 chip->monitoring_volume[i] =
1005 !!ucontrol->value.integer.value[i];
1006 mixart_update_monitoring(chip, i);
1007 changed = 1;
1008 }
1009 }
1010 mutex_unlock(&chip->mgr->mixer_mutex);
1011 return changed;
1012 }
1013
1014 static const struct snd_kcontrol_new mixart_control_monitor_vol = {
1015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1016 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1017 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1018 .name = "Monitoring Volume",
1019 .info = mixart_digital_vol_info,
1020 .get = mixart_monitor_vol_get,
1021 .put = mixart_monitor_vol_put,
1022 .tlv = { .p = db_scale_digital },
1023 };
1024
1025
1026
1027
1028
1029 static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1030 {
1031 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1032 mutex_lock(&chip->mgr->mixer_mutex);
1033 ucontrol->value.integer.value[0] = chip->monitoring_active[0];
1034 ucontrol->value.integer.value[1] = chip->monitoring_active[1];
1035 mutex_unlock(&chip->mgr->mixer_mutex);
1036 return 0;
1037 }
1038
1039 static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1040 {
1041 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1042 int changed = 0;
1043 int i;
1044 mutex_lock(&chip->mgr->mixer_mutex);
1045 for (i = 0; i < 2; i++) {
1046 if (chip->monitoring_active[i] !=
1047 ucontrol->value.integer.value[i]) {
1048 chip->monitoring_active[i] =
1049 !!ucontrol->value.integer.value[i];
1050 changed |= (1<<i);
1051 }
1052 }
1053 if (changed) {
1054
1055 int allocate = chip->monitoring_active[0] ||
1056 chip->monitoring_active[1];
1057 if (allocate) {
1058
1059 snd_mixart_add_ref_pipe(chip, MIXART_PCM_ANALOG, 0, 1);
1060
1061 snd_mixart_add_ref_pipe(chip, MIXART_PCM_ANALOG, 1, 1);
1062 }
1063 if (changed & 0x01)
1064 mixart_update_monitoring(chip, 0);
1065 if (changed & 0x02)
1066 mixart_update_monitoring(chip, 1);
1067 if (!allocate) {
1068
1069 snd_mixart_kill_ref_pipe(chip->mgr,
1070 &chip->pipe_in_ana, 1);
1071
1072 snd_mixart_kill_ref_pipe(chip->mgr,
1073 &chip->pipe_out_ana, 1);
1074 }
1075 }
1076
1077 mutex_unlock(&chip->mgr->mixer_mutex);
1078 return (changed != 0);
1079 }
1080
1081 static const struct snd_kcontrol_new mixart_control_monitor_sw = {
1082 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1083 .name = "Monitoring Switch",
1084 .info = mixart_sw_info,
1085 .get = mixart_monitor_sw_get,
1086 .put = mixart_monitor_sw_put
1087 };
1088
1089
1090 static void mixart_reset_audio_levels(struct snd_mixart *chip)
1091 {
1092
1093 mixart_update_analog_audio_level(chip, 0);
1094
1095 if(chip->chip_idx < 2) {
1096 mixart_update_analog_audio_level(chip, 1);
1097 }
1098 return;
1099 }
1100
1101
1102 int snd_mixart_create_mixer(struct mixart_mgr *mgr)
1103 {
1104 struct snd_mixart *chip;
1105 int err, i;
1106
1107 mutex_init(&mgr->mixer_mutex);
1108
1109 for(i=0; i<mgr->num_cards; i++) {
1110 struct snd_kcontrol_new temp;
1111 chip = mgr->chip[i];
1112
1113
1114 temp = mixart_control_analog_level;
1115 temp.name = "Master Playback Volume";
1116 temp.private_value = 0;
1117 err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
1118 if (err < 0)
1119 return err;
1120
1121 err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_output_switch, chip));
1122 if (err < 0)
1123 return err;
1124
1125
1126 if(i<2) {
1127 temp = mixart_control_analog_level;
1128 temp.name = "Master Capture Volume";
1129 temp.private_value = 1;
1130 err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
1131 if (err < 0)
1132 return err;
1133 }
1134
1135 temp = snd_mixart_pcm_vol;
1136 temp.name = "PCM Playback Volume";
1137 temp.count = MIXART_PLAYBACK_STREAMS;
1138 temp.private_value = 0;
1139 err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
1140 if (err < 0)
1141 return err;
1142
1143 temp.name = "PCM Capture Volume";
1144 temp.count = 1;
1145 temp.private_value = MIXART_VOL_REC_MASK;
1146 err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
1147 if (err < 0)
1148 return err;
1149
1150 if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1151 temp.name = "AES Playback Volume";
1152 temp.count = MIXART_PLAYBACK_STREAMS;
1153 temp.private_value = MIXART_VOL_AES_MASK;
1154 err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
1155 if (err < 0)
1156 return err;
1157
1158 temp.name = "AES Capture Volume";
1159 temp.count = 0;
1160 temp.private_value = MIXART_VOL_REC_MASK | MIXART_VOL_AES_MASK;
1161 err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
1162 if (err < 0)
1163 return err;
1164 }
1165 temp = mixart_control_pcm_switch;
1166 temp.name = "PCM Playback Switch";
1167 temp.private_value = 0;
1168 err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
1169 if (err < 0)
1170 return err;
1171
1172 if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1173 temp.name = "AES Playback Switch";
1174 temp.private_value = MIXART_VOL_AES_MASK;
1175 err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
1176 if (err < 0)
1177 return err;
1178 }
1179
1180
1181 err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_vol, chip));
1182 if (err < 0)
1183 return err;
1184 err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_sw, chip));
1185 if (err < 0)
1186 return err;
1187
1188
1189 mixart_reset_audio_levels(chip);
1190 }
1191 return 0;
1192 }