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