1 /* 2 * Support for Digigram Lola PCI-e boards 3 * 4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 * more details. 15 * 16 * You should have received a copy of the GNU General Public License along with 17 * this program; if not, write to the Free Software Foundation, Inc., 59 18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 21 #include <linux/kernel.h> 22 #include <linux/init.h> 23 #include <linux/vmalloc.h> 24 #include <linux/io.h> 25 #include <sound/core.h> 26 #include <sound/control.h> 27 #include <sound/pcm.h> 28 #include <sound/tlv.h> 29 #include "lola.h" 30 31 static int lola_init_pin(struct lola *chip, struct lola_pin *pin, 32 int dir, int nid) 33 { 34 unsigned int val; 35 int err; 36 37 pin->nid = nid; 38 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); 39 if (err < 0) { 40 dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid); 41 return err; 42 } 43 val &= 0x00f00fff; /* test TYPE and bits 0..11 */ 44 if (val == 0x00400200) /* Type = 4, Digital = 1 */ 45 pin->is_analog = false; 46 else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */ 47 pin->is_analog = true; 48 else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */ 49 pin->is_analog = true; 50 else { 51 dev_err(chip->card->dev, "Invalid wcaps 0x%x for 0x%x\n", val, nid); 52 return -EINVAL; 53 } 54 55 /* analog parameters only following, so continue in case of Digital pin 56 */ 57 if (!pin->is_analog) 58 return 0; 59 60 if (dir == PLAY) 61 err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val); 62 else 63 err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val); 64 if (err < 0) { 65 dev_err(chip->card->dev, "Can't read AMP-caps for 0x%x\n", nid); 66 return err; 67 } 68 69 pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val); 70 pin->amp_step_size = LOLA_AMP_STEP_SIZE(val); 71 pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val); 72 if (pin->amp_num_steps) { 73 /* zero as mute state */ 74 pin->amp_num_steps++; 75 pin->amp_step_size++; 76 } 77 pin->amp_offset = LOLA_AMP_OFFSET(val); 78 79 err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, 80 NULL); 81 if (err < 0) { 82 dev_err(chip->card->dev, "Can't get MAX_LEVEL 0x%x\n", nid); 83 return err; 84 } 85 pin->max_level = val & 0x3ff; /* 10 bits */ 86 87 pin->config_default_reg = 0; 88 pin->fixed_gain_list_len = 0; 89 pin->cur_gain_step = 0; 90 91 return 0; 92 } 93 94 int lola_init_pins(struct lola *chip, int dir, int *nidp) 95 { 96 int i, err, nid; 97 nid = *nidp; 98 for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) { 99 err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid); 100 if (err < 0) 101 return err; 102 if (chip->pin[dir].pins[i].is_analog) 103 chip->pin[dir].num_analog_pins++; 104 } 105 *nidp = nid; 106 return 0; 107 } 108 109 void lola_free_mixer(struct lola *chip) 110 { 111 vfree(chip->mixer.array_saved); 112 } 113 114 int lola_init_mixer_widget(struct lola *chip, int nid) 115 { 116 unsigned int val; 117 int err; 118 119 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); 120 if (err < 0) { 121 dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid); 122 return err; 123 } 124 125 if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */ 126 dev_dbg(chip->card->dev, "No valid mixer widget\n"); 127 return 0; 128 } 129 130 chip->mixer.nid = nid; 131 chip->mixer.caps = val; 132 chip->mixer.array = (struct lola_mixer_array __iomem *) 133 (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE); 134 135 /* reserve memory to copy mixer data for sleep mode transitions */ 136 chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array)); 137 138 /* mixer matrix sources are physical input data and play streams */ 139 chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams; 140 chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins; 141 142 /* mixer matrix destinations are record streams and physical output */ 143 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams; 144 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins; 145 146 /* mixer matrix may have unused areas between PhysIn and 147 * Play or Record and PhysOut zones 148 */ 149 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins + 150 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val); 151 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins + 152 LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val); 153 154 /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones) 155 * +-+ 0-------8------16-------8------16 156 * | | | | | | | 157 * |s| | INPUT | | INPUT | | 158 * | |->| -> |unused | -> |unused | 159 * |r| |CAPTURE| | OUTPUT| | 160 * | | | MIX | | MIX | | 161 * |c| 8-------------------------------- 162 * | | | | | | | 163 * | | | | | | | 164 * |g| |unused |unused |unused |unused | 165 * | | | | | | | 166 * |a| | | | | | 167 * | | 16------------------------------- 168 * |i| | | | | | 169 * | | | PLAYBK| | PLAYBK| | 170 * |n|->| -> |unused | -> |unused | 171 * | | |CAPTURE| | OUTPUT| | 172 * | | | MIX | | MIX | | 173 * |a| 8-------------------------------- 174 * |r| | | | | | 175 * |r| | | | | | 176 * |a| |unused |unused |unused |unused | 177 * |y| | | | | | 178 * | | | | | | | 179 * +++ 16--|---------------|------------ 180 * +---V---------------V-----------+ 181 * | dest_mix_gain_enable array | 182 * +-------------------------------+ 183 */ 184 /* example : MixerMatrix of LoLa280 185 * +-+ 0-------8-2 186 * | | | | | 187 * |s| | INPUT | | INPUT 188 * |r|->| -> | | -> 189 * |c| |CAPTURE| | <- OUTPUT 190 * | | | MIX | | MIX 191 * |g| 8---------- 192 * |a| | | | 193 * |i| | PLAYBK| | PLAYBACK 194 * |n|->| -> | | -> 195 * | | |CAPTURE| | <- OUTPUT 196 * |a| | MIX | | MIX 197 * |r| 8---|----|- 198 * |r| +---V----V-------------------+ 199 * |a| | dest_mix_gain_enable array | 200 * |y| +----------------------------+ 201 */ 202 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT || 203 chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) { 204 dev_err(chip->card->dev, "Invalid mixer widget size\n"); 205 return -EINVAL; 206 } 207 208 chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) | 209 (((1U << chip->mixer.src_stream_outs) - 1) 210 << chip->mixer.src_stream_out_ofs); 211 chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) | 212 (((1U << chip->mixer.dest_phys_outs) - 1) 213 << chip->mixer.dest_phys_out_ofs); 214 215 dev_dbg(chip->card->dev, "Mixer src_mask=%x, dest_mask=%x\n", 216 chip->mixer.src_mask, chip->mixer.dest_mask); 217 218 return 0; 219 } 220 221 static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id, 222 unsigned short gain, bool on) 223 { 224 unsigned int oldval, val; 225 226 if (!(chip->mixer.src_mask & (1 << id))) 227 return -EINVAL; 228 oldval = val = readl(&chip->mixer.array->src_gain_enable); 229 if (on) 230 val |= (1 << id); 231 else 232 val &= ~(1 << id); 233 /* test if values unchanged */ 234 if ((val == oldval) && 235 (gain == readw(&chip->mixer.array->src_gain[id]))) 236 return 0; 237 238 dev_dbg(chip->card->dev, 239 "lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n", 240 id, gain, val); 241 writew(gain, &chip->mixer.array->src_gain[id]); 242 writel(val, &chip->mixer.array->src_gain_enable); 243 lola_codec_flush(chip); 244 /* inform micro-controller about the new source gain */ 245 return lola_codec_write(chip, chip->mixer.nid, 246 LOLA_VERB_SET_SOURCE_GAIN, id, 0); 247 } 248 249 #if 0 /* not used */ 250 static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask, 251 unsigned short *gains) 252 { 253 int i; 254 255 if ((chip->mixer.src_mask & mask) != mask) 256 return -EINVAL; 257 for (i = 0; i < LOLA_MIXER_DIM; i++) { 258 if (mask & (1 << i)) { 259 writew(*gains, &chip->mixer.array->src_gain[i]); 260 gains++; 261 } 262 } 263 writel(mask, &chip->mixer.array->src_gain_enable); 264 lola_codec_flush(chip); 265 if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) { 266 /* update for all srcs at once */ 267 return lola_codec_write(chip, chip->mixer.nid, 268 LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0); 269 } 270 /* update manually */ 271 for (i = 0; i < LOLA_MIXER_DIM; i++) { 272 if (mask & (1 << i)) { 273 lola_codec_write(chip, chip->mixer.nid, 274 LOLA_VERB_SET_SOURCE_GAIN, i, 0); 275 } 276 } 277 return 0; 278 } 279 #endif /* not used */ 280 281 static int lola_mixer_set_mapping_gain(struct lola *chip, 282 unsigned int src, unsigned int dest, 283 unsigned short gain, bool on) 284 { 285 unsigned int val; 286 287 if (!(chip->mixer.src_mask & (1 << src)) || 288 !(chip->mixer.dest_mask & (1 << dest))) 289 return -EINVAL; 290 if (on) 291 writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]); 292 val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]); 293 if (on) 294 val |= (1 << src); 295 else 296 val &= ~(1 << src); 297 writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]); 298 lola_codec_flush(chip); 299 return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN, 300 src, dest); 301 } 302 303 #if 0 /* not used */ 304 static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id, 305 unsigned int mask, unsigned short *gains) 306 { 307 int i; 308 309 if (!(chip->mixer.dest_mask & (1 << id)) || 310 (chip->mixer.src_mask & mask) != mask) 311 return -EINVAL; 312 for (i = 0; i < LOLA_MIXER_DIM; i++) { 313 if (mask & (1 << i)) { 314 writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]); 315 gains++; 316 } 317 } 318 writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]); 319 lola_codec_flush(chip); 320 /* update for all dests at once */ 321 return lola_codec_write(chip, chip->mixer.nid, 322 LOLA_VERB_SET_DESTINATION_GAIN, id, 0); 323 } 324 #endif /* not used */ 325 326 /* 327 */ 328 329 static int set_analog_volume(struct lola *chip, int dir, 330 unsigned int idx, unsigned int val, 331 bool external_call); 332 333 int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute) 334 { 335 struct lola_pin *pin; 336 int idx, max_idx; 337 338 pin = chip->pin[dir].pins; 339 max_idx = chip->pin[dir].num_pins; 340 for (idx = 0; idx < max_idx; idx++) { 341 if (pin[idx].is_analog) { 342 unsigned int val = mute ? 0 : pin[idx].cur_gain_step; 343 /* set volume and do not save the value */ 344 set_analog_volume(chip, dir, idx, val, false); 345 } 346 } 347 return lola_codec_flush(chip); 348 } 349 350 void lola_save_mixer(struct lola *chip) 351 { 352 /* mute analog output */ 353 if (chip->mixer.array_saved) { 354 /* store contents of mixer array */ 355 memcpy_fromio(chip->mixer.array_saved, chip->mixer.array, 356 sizeof(*chip->mixer.array)); 357 } 358 lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */ 359 } 360 361 void lola_restore_mixer(struct lola *chip) 362 { 363 int i; 364 365 /*lola_reset_setups(chip);*/ 366 if (chip->mixer.array_saved) { 367 /* restore contents of mixer array */ 368 memcpy_toio(chip->mixer.array, chip->mixer.array_saved, 369 sizeof(*chip->mixer.array)); 370 /* inform micro-controller about all restored values 371 * and ignore return values 372 */ 373 for (i = 0; i < chip->mixer.src_phys_ins; i++) 374 lola_codec_write(chip, chip->mixer.nid, 375 LOLA_VERB_SET_SOURCE_GAIN, 376 i, 0); 377 for (i = 0; i < chip->mixer.src_stream_outs; i++) 378 lola_codec_write(chip, chip->mixer.nid, 379 LOLA_VERB_SET_SOURCE_GAIN, 380 chip->mixer.src_stream_out_ofs + i, 0); 381 for (i = 0; i < chip->mixer.dest_stream_ins; i++) 382 lola_codec_write(chip, chip->mixer.nid, 383 LOLA_VERB_SET_DESTINATION_GAIN, 384 i, 0); 385 for (i = 0; i < chip->mixer.dest_phys_outs; i++) 386 lola_codec_write(chip, chip->mixer.nid, 387 LOLA_VERB_SET_DESTINATION_GAIN, 388 chip->mixer.dest_phys_out_ofs + i, 0); 389 lola_codec_flush(chip); 390 } 391 } 392 393 /* 394 */ 395 396 static int set_analog_volume(struct lola *chip, int dir, 397 unsigned int idx, unsigned int val, 398 bool external_call) 399 { 400 struct lola_pin *pin; 401 int err; 402 403 if (idx >= chip->pin[dir].num_pins) 404 return -EINVAL; 405 pin = &chip->pin[dir].pins[idx]; 406 if (!pin->is_analog || pin->amp_num_steps <= val) 407 return -EINVAL; 408 if (external_call && pin->cur_gain_step == val) 409 return 0; 410 if (external_call) 411 lola_codec_flush(chip); 412 dev_dbg(chip->card->dev, 413 "set_analog_volume (dir=%d idx=%d, volume=%d)\n", 414 dir, idx, val); 415 err = lola_codec_write(chip, pin->nid, 416 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0); 417 if (err < 0) 418 return err; 419 if (external_call) 420 pin->cur_gain_step = val; 421 return 0; 422 } 423 424 int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update) 425 { 426 int ret = 0; 427 int success = 0; 428 int n, err; 429 430 /* SRC can be activated and the dwInputSRCMask is valid? */ 431 if ((chip->input_src_caps_mask & src_mask) != src_mask) 432 return -EINVAL; 433 /* handle all even Inputs - SRC is a stereo setting !!! */ 434 for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) { 435 unsigned int mask = 3U << n; /* handle the stereo case */ 436 unsigned int new_src, src_state; 437 if (!(chip->input_src_caps_mask & mask)) 438 continue; 439 /* if one IO needs SRC, both stereo IO will get SRC */ 440 new_src = (src_mask & mask) != 0; 441 if (update) { 442 src_state = (chip->input_src_mask & mask) != 0; 443 if (src_state == new_src) 444 continue; /* nothing to change for this IO */ 445 } 446 err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid, 447 LOLA_VERB_SET_SRC, new_src, 0); 448 if (!err) 449 success++; 450 else 451 ret = err; 452 } 453 if (success) 454 ret = lola_codec_flush(chip); 455 if (!ret) 456 chip->input_src_mask = src_mask; 457 return ret; 458 } 459 460 /* 461 */ 462 static int init_mixer_values(struct lola *chip) 463 { 464 int i; 465 466 /* all sample rate converters on */ 467 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false); 468 469 /* clear all mixer matrix settings */ 470 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array)); 471 /* inform firmware about all updated matrix columns - capture part */ 472 for (i = 0; i < chip->mixer.dest_stream_ins; i++) 473 lola_codec_write(chip, chip->mixer.nid, 474 LOLA_VERB_SET_DESTINATION_GAIN, 475 i, 0); 476 /* inform firmware about all updated matrix columns - output part */ 477 for (i = 0; i < chip->mixer.dest_phys_outs; i++) 478 lola_codec_write(chip, chip->mixer.nid, 479 LOLA_VERB_SET_DESTINATION_GAIN, 480 chip->mixer.dest_phys_out_ofs + i, 0); 481 482 /* set all digital input source (master) gains to 0dB */ 483 for (i = 0; i < chip->mixer.src_phys_ins; i++) 484 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */ 485 486 /* set all digital playback source (master) gains to 0dB */ 487 for (i = 0; i < chip->mixer.src_stream_outs; i++) 488 lola_mixer_set_src_gain(chip, 489 i + chip->mixer.src_stream_out_ofs, 490 336, true); /* 0dB */ 491 /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */ 492 for (i = 0; i < chip->mixer.dest_stream_ins; i++) { 493 int src = i % chip->mixer.src_phys_ins; 494 lola_mixer_set_mapping_gain(chip, src, i, 336, true); 495 } 496 /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT 497 * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0) 498 * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1) 499 */ 500 for (i = 0; i < chip->mixer.src_stream_outs; i++) { 501 int src = chip->mixer.src_stream_out_ofs + i; 502 int dst = chip->mixer.dest_phys_out_ofs + 503 i % chip->mixer.dest_phys_outs; 504 lola_mixer_set_mapping_gain(chip, src, dst, 336, true); 505 } 506 return 0; 507 } 508 509 /* 510 * analog mixer control element 511 */ 512 static int lola_analog_vol_info(struct snd_kcontrol *kcontrol, 513 struct snd_ctl_elem_info *uinfo) 514 { 515 struct lola *chip = snd_kcontrol_chip(kcontrol); 516 int dir = kcontrol->private_value; 517 518 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 519 uinfo->count = chip->pin[dir].num_pins; 520 uinfo->value.integer.min = 0; 521 uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps; 522 return 0; 523 } 524 525 static int lola_analog_vol_get(struct snd_kcontrol *kcontrol, 526 struct snd_ctl_elem_value *ucontrol) 527 { 528 struct lola *chip = snd_kcontrol_chip(kcontrol); 529 int dir = kcontrol->private_value; 530 int i; 531 532 for (i = 0; i < chip->pin[dir].num_pins; i++) 533 ucontrol->value.integer.value[i] = 534 chip->pin[dir].pins[i].cur_gain_step; 535 return 0; 536 } 537 538 static int lola_analog_vol_put(struct snd_kcontrol *kcontrol, 539 struct snd_ctl_elem_value *ucontrol) 540 { 541 struct lola *chip = snd_kcontrol_chip(kcontrol); 542 int dir = kcontrol->private_value; 543 int i, err; 544 545 for (i = 0; i < chip->pin[dir].num_pins; i++) { 546 err = set_analog_volume(chip, dir, i, 547 ucontrol->value.integer.value[i], 548 true); 549 if (err < 0) 550 return err; 551 } 552 return 0; 553 } 554 555 static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 556 unsigned int size, unsigned int __user *tlv) 557 { 558 struct lola *chip = snd_kcontrol_chip(kcontrol); 559 int dir = kcontrol->private_value; 560 unsigned int val1, val2; 561 struct lola_pin *pin; 562 563 if (size < 4 * sizeof(unsigned int)) 564 return -ENOMEM; 565 pin = &chip->pin[dir].pins[0]; 566 567 val2 = pin->amp_step_size * 25; 568 val1 = -1 * (int)pin->amp_offset * (int)val2; 569 #ifdef TLV_DB_SCALE_MUTE 570 val2 |= TLV_DB_SCALE_MUTE; 571 #endif 572 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv)) 573 return -EFAULT; 574 if (put_user(2 * sizeof(unsigned int), tlv + 1)) 575 return -EFAULT; 576 if (put_user(val1, tlv + 2)) 577 return -EFAULT; 578 if (put_user(val2, tlv + 3)) 579 return -EFAULT; 580 return 0; 581 } 582 583 static struct snd_kcontrol_new lola_analog_mixer = { 584 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 585 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 586 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 587 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), 588 .info = lola_analog_vol_info, 589 .get = lola_analog_vol_get, 590 .put = lola_analog_vol_put, 591 .tlv.c = lola_analog_vol_tlv, 592 }; 593 594 static int create_analog_mixer(struct lola *chip, int dir, char *name) 595 { 596 if (!chip->pin[dir].num_pins) 597 return 0; 598 /* no analog volumes on digital only adapters */ 599 if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins) 600 return 0; 601 lola_analog_mixer.name = name; 602 lola_analog_mixer.private_value = dir; 603 return snd_ctl_add(chip->card, 604 snd_ctl_new1(&lola_analog_mixer, chip)); 605 } 606 607 /* 608 * Hardware sample rate converter on digital input 609 */ 610 static int lola_input_src_info(struct snd_kcontrol *kcontrol, 611 struct snd_ctl_elem_info *uinfo) 612 { 613 struct lola *chip = snd_kcontrol_chip(kcontrol); 614 615 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 616 uinfo->count = chip->pin[CAPT].num_pins; 617 uinfo->value.integer.min = 0; 618 uinfo->value.integer.max = 1; 619 return 0; 620 } 621 622 static int lola_input_src_get(struct snd_kcontrol *kcontrol, 623 struct snd_ctl_elem_value *ucontrol) 624 { 625 struct lola *chip = snd_kcontrol_chip(kcontrol); 626 int i; 627 628 for (i = 0; i < chip->pin[CAPT].num_pins; i++) 629 ucontrol->value.integer.value[i] = 630 !!(chip->input_src_mask & (1 << i)); 631 return 0; 632 } 633 634 static int lola_input_src_put(struct snd_kcontrol *kcontrol, 635 struct snd_ctl_elem_value *ucontrol) 636 { 637 struct lola *chip = snd_kcontrol_chip(kcontrol); 638 int i; 639 unsigned int mask; 640 641 mask = 0; 642 for (i = 0; i < chip->pin[CAPT].num_pins; i++) 643 if (ucontrol->value.integer.value[i]) 644 mask |= 1 << i; 645 return lola_set_src_config(chip, mask, true); 646 } 647 648 static const struct snd_kcontrol_new lola_input_src_mixer = { 649 .name = "Digital SRC Capture Switch", 650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 651 .info = lola_input_src_info, 652 .get = lola_input_src_get, 653 .put = lola_input_src_put, 654 }; 655 656 /* 657 * Lola16161 or Lola881 can have Hardware sample rate converters 658 * on its digital input pins 659 */ 660 static int create_input_src_mixer(struct lola *chip) 661 { 662 if (!chip->input_src_caps_mask) 663 return 0; 664 665 return snd_ctl_add(chip->card, 666 snd_ctl_new1(&lola_input_src_mixer, chip)); 667 } 668 669 /* 670 * src gain mixer 671 */ 672 static int lola_src_gain_info(struct snd_kcontrol *kcontrol, 673 struct snd_ctl_elem_info *uinfo) 674 { 675 unsigned int count = (kcontrol->private_value >> 8) & 0xff; 676 677 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 678 uinfo->count = count; 679 uinfo->value.integer.min = 0; 680 uinfo->value.integer.max = 409; 681 return 0; 682 } 683 684 static int lola_src_gain_get(struct snd_kcontrol *kcontrol, 685 struct snd_ctl_elem_value *ucontrol) 686 { 687 struct lola *chip = snd_kcontrol_chip(kcontrol); 688 unsigned int ofs = kcontrol->private_value & 0xff; 689 unsigned int count = (kcontrol->private_value >> 8) & 0xff; 690 unsigned int mask, i; 691 692 mask = readl(&chip->mixer.array->src_gain_enable); 693 for (i = 0; i < count; i++) { 694 unsigned int idx = ofs + i; 695 unsigned short val; 696 if (!(chip->mixer.src_mask & (1 << idx))) 697 return -EINVAL; 698 if (mask & (1 << idx)) 699 val = readw(&chip->mixer.array->src_gain[idx]) + 1; 700 else 701 val = 0; 702 ucontrol->value.integer.value[i] = val; 703 } 704 return 0; 705 } 706 707 static int lola_src_gain_put(struct snd_kcontrol *kcontrol, 708 struct snd_ctl_elem_value *ucontrol) 709 { 710 struct lola *chip = snd_kcontrol_chip(kcontrol); 711 unsigned int ofs = kcontrol->private_value & 0xff; 712 unsigned int count = (kcontrol->private_value >> 8) & 0xff; 713 int i, err; 714 715 for (i = 0; i < count; i++) { 716 unsigned int idx = ofs + i; 717 unsigned short val = ucontrol->value.integer.value[i]; 718 if (val) 719 val--; 720 err = lola_mixer_set_src_gain(chip, idx, val, !!val); 721 if (err < 0) 722 return err; 723 } 724 return 0; 725 } 726 727 /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */ 728 static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1); 729 730 static struct snd_kcontrol_new lola_src_gain_mixer = { 731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 732 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 733 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 734 .info = lola_src_gain_info, 735 .get = lola_src_gain_get, 736 .put = lola_src_gain_put, 737 .tlv.p = lola_src_gain_tlv, 738 }; 739 740 static int create_src_gain_mixer(struct lola *chip, 741 int num, int ofs, char *name) 742 { 743 lola_src_gain_mixer.name = name; 744 lola_src_gain_mixer.private_value = ofs + (num << 8); 745 return snd_ctl_add(chip->card, 746 snd_ctl_new1(&lola_src_gain_mixer, chip)); 747 } 748 749 #if 0 /* not used */ 750 /* 751 * destination gain (matrix-like) mixer 752 */ 753 static int lola_dest_gain_info(struct snd_kcontrol *kcontrol, 754 struct snd_ctl_elem_info *uinfo) 755 { 756 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; 757 758 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 759 uinfo->count = src_num; 760 uinfo->value.integer.min = 0; 761 uinfo->value.integer.max = 433; 762 return 0; 763 } 764 765 static int lola_dest_gain_get(struct snd_kcontrol *kcontrol, 766 struct snd_ctl_elem_value *ucontrol) 767 { 768 struct lola *chip = snd_kcontrol_chip(kcontrol); 769 unsigned int src_ofs = kcontrol->private_value & 0xff; 770 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; 771 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff; 772 unsigned int dst, mask, i; 773 774 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs; 775 mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]); 776 for (i = 0; i < src_num; i++) { 777 unsigned int src = src_ofs + i; 778 unsigned short val; 779 if (!(chip->mixer.src_mask & (1 << src))) 780 return -EINVAL; 781 if (mask & (1 << dst)) 782 val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1; 783 else 784 val = 0; 785 ucontrol->value.integer.value[i] = val; 786 } 787 return 0; 788 } 789 790 static int lola_dest_gain_put(struct snd_kcontrol *kcontrol, 791 struct snd_ctl_elem_value *ucontrol) 792 { 793 struct lola *chip = snd_kcontrol_chip(kcontrol); 794 unsigned int src_ofs = kcontrol->private_value & 0xff; 795 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; 796 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff; 797 unsigned int dst, mask; 798 unsigned short gains[MAX_STREAM_COUNT]; 799 int i, num; 800 801 mask = 0; 802 num = 0; 803 for (i = 0; i < src_num; i++) { 804 unsigned short val = ucontrol->value.integer.value[i]; 805 if (val) { 806 gains[num++] = val - 1; 807 mask |= 1 << i; 808 } 809 } 810 mask <<= src_ofs; 811 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs; 812 return lola_mixer_set_dest_gains(chip, dst, mask, gains); 813 } 814 815 static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1); 816 817 static struct snd_kcontrol_new lola_dest_gain_mixer = { 818 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 819 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 820 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 821 .info = lola_dest_gain_info, 822 .get = lola_dest_gain_get, 823 .put = lola_dest_gain_put, 824 .tlv.p = lola_dest_gain_tlv, 825 }; 826 827 static int create_dest_gain_mixer(struct lola *chip, 828 int src_num, int src_ofs, 829 int num, int ofs, char *name) 830 { 831 lola_dest_gain_mixer.count = num; 832 lola_dest_gain_mixer.name = name; 833 lola_dest_gain_mixer.private_value = 834 src_ofs + (src_num << 8) + (ofs << 16) + (num << 24); 835 return snd_ctl_add(chip->card, 836 snd_ctl_new1(&lola_dest_gain_mixer, chip)); 837 } 838 #endif /* not used */ 839 840 /* 841 */ 842 int lola_create_mixer(struct lola *chip) 843 { 844 int err; 845 846 err = create_analog_mixer(chip, PLAY, "Analog Playback Volume"); 847 if (err < 0) 848 return err; 849 err = create_analog_mixer(chip, CAPT, "Analog Capture Volume"); 850 if (err < 0) 851 return err; 852 err = create_input_src_mixer(chip); 853 if (err < 0) 854 return err; 855 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0, 856 "Digital Capture Volume"); 857 if (err < 0) 858 return err; 859 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs, 860 chip->mixer.src_stream_out_ofs, 861 "Digital Playback Volume"); 862 if (err < 0) 863 return err; 864 #if 0 865 /* FIXME: buggy mixer matrix handling */ 866 err = create_dest_gain_mixer(chip, 867 chip->mixer.src_phys_ins, 0, 868 chip->mixer.dest_stream_ins, 0, 869 "Line Capture Volume"); 870 if (err < 0) 871 return err; 872 err = create_dest_gain_mixer(chip, 873 chip->mixer.src_stream_outs, 874 chip->mixer.src_stream_out_ofs, 875 chip->mixer.dest_stream_ins, 0, 876 "Stream-Loopback Capture Volume"); 877 if (err < 0) 878 return err; 879 err = create_dest_gain_mixer(chip, 880 chip->mixer.src_phys_ins, 0, 881 chip->mixer.dest_phys_outs, 882 chip->mixer.dest_phys_out_ofs, 883 "Line-Loopback Playback Volume"); 884 if (err < 0) 885 return err; 886 err = create_dest_gain_mixer(chip, 887 chip->mixer.src_stream_outs, 888 chip->mixer.src_stream_out_ofs, 889 chip->mixer.dest_phys_outs, 890 chip->mixer.dest_phys_out_ofs, 891 "Stream Playback Volume"); 892 if (err < 0) 893 return err; 894 #endif /* FIXME */ 895 return init_mixer_values(chip); 896 } 897