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 __devinit 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 printk(KERN_ERR SFX "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 printk(KERN_ERR SFX "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 printk(KERN_ERR SFX "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 printk(KERN_ERR SFX "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 __devinit 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 __devinit 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 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid); 123 return err; 124 } 125 126 if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */ 127 snd_printdd("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 printk(KERN_ERR SFX "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 snd_printdd("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 snd_printdd("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 snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n", 413 dir, idx, val); 414 err = lola_codec_write(chip, pin->nid, 415 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0); 416 if (err < 0) 417 return err; 418 if (external_call) 419 pin->cur_gain_step = val; 420 return 0; 421 } 422 423 int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update) 424 { 425 int ret = 0; 426 int success = 0; 427 int n, err; 428 429 /* SRC can be activated and the dwInputSRCMask is valid? */ 430 if ((chip->input_src_caps_mask & src_mask) != src_mask) 431 return -EINVAL; 432 /* handle all even Inputs - SRC is a stereo setting !!! */ 433 for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) { 434 unsigned int mask = 3U << n; /* handle the stereo case */ 435 unsigned int new_src, src_state; 436 if (!(chip->input_src_caps_mask & mask)) 437 continue; 438 /* if one IO needs SRC, both stereo IO will get SRC */ 439 new_src = (src_mask & mask) != 0; 440 if (update) { 441 src_state = (chip->input_src_mask & mask) != 0; 442 if (src_state == new_src) 443 continue; /* nothing to change for this IO */ 444 } 445 err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid, 446 LOLA_VERB_SET_SRC, new_src, 0); 447 if (!err) 448 success++; 449 else 450 ret = err; 451 } 452 if (success) 453 ret = lola_codec_flush(chip); 454 if (!ret) 455 chip->input_src_mask = src_mask; 456 return ret; 457 } 458 459 /* 460 */ 461 static int init_mixer_values(struct lola *chip) 462 { 463 int i; 464 465 /* all sample rate converters on */ 466 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false); 467 468 /* clear all mixer matrix settings */ 469 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array)); 470 /* inform firmware about all updated matrix columns - capture part */ 471 for (i = 0; i < chip->mixer.dest_stream_ins; i++) 472 lola_codec_write(chip, chip->mixer.nid, 473 LOLA_VERB_SET_DESTINATION_GAIN, 474 i, 0); 475 /* inform firmware about all updated matrix columns - output part */ 476 for (i = 0; i < chip->mixer.dest_phys_outs; i++) 477 lola_codec_write(chip, chip->mixer.nid, 478 LOLA_VERB_SET_DESTINATION_GAIN, 479 chip->mixer.dest_phys_out_ofs + i, 0); 480 481 /* set all digital input source (master) gains to 0dB */ 482 for (i = 0; i < chip->mixer.src_phys_ins; i++) 483 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */ 484 485 /* set all digital playback source (master) gains to 0dB */ 486 for (i = 0; i < chip->mixer.src_stream_outs; i++) 487 lola_mixer_set_src_gain(chip, 488 i + chip->mixer.src_stream_out_ofs, 489 336, true); /* 0dB */ 490 /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */ 491 for (i = 0; i < chip->mixer.dest_stream_ins; i++) { 492 int src = i % chip->mixer.src_phys_ins; 493 lola_mixer_set_mapping_gain(chip, src, i, 336, true); 494 } 495 /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT 496 * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0) 497 * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1) 498 */ 499 for (i = 0; i < chip->mixer.src_stream_outs; i++) { 500 int src = chip->mixer.src_stream_out_ofs + i; 501 int dst = chip->mixer.dest_phys_out_ofs + 502 i % chip->mixer.dest_phys_outs; 503 lola_mixer_set_mapping_gain(chip, src, dst, 336, true); 504 } 505 return 0; 506 } 507 508 /* 509 * analog mixer control element 510 */ 511 static int lola_analog_vol_info(struct snd_kcontrol *kcontrol, 512 struct snd_ctl_elem_info *uinfo) 513 { 514 struct lola *chip = snd_kcontrol_chip(kcontrol); 515 int dir = kcontrol->private_value; 516 517 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 518 uinfo->count = chip->pin[dir].num_pins; 519 uinfo->value.integer.min = 0; 520 uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps; 521 return 0; 522 } 523 524 static int lola_analog_vol_get(struct snd_kcontrol *kcontrol, 525 struct snd_ctl_elem_value *ucontrol) 526 { 527 struct lola *chip = snd_kcontrol_chip(kcontrol); 528 int dir = kcontrol->private_value; 529 int i; 530 531 for (i = 0; i < chip->pin[dir].num_pins; i++) 532 ucontrol->value.integer.value[i] = 533 chip->pin[dir].pins[i].cur_gain_step; 534 return 0; 535 } 536 537 static int lola_analog_vol_put(struct snd_kcontrol *kcontrol, 538 struct snd_ctl_elem_value *ucontrol) 539 { 540 struct lola *chip = snd_kcontrol_chip(kcontrol); 541 int dir = kcontrol->private_value; 542 int i, err; 543 544 for (i = 0; i < chip->pin[dir].num_pins; i++) { 545 err = set_analog_volume(chip, dir, i, 546 ucontrol->value.integer.value[i], 547 true); 548 if (err < 0) 549 return err; 550 } 551 return 0; 552 } 553 554 static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 555 unsigned int size, unsigned int __user *tlv) 556 { 557 struct lola *chip = snd_kcontrol_chip(kcontrol); 558 int dir = kcontrol->private_value; 559 unsigned int val1, val2; 560 struct lola_pin *pin; 561 562 if (size < 4 * sizeof(unsigned int)) 563 return -ENOMEM; 564 pin = &chip->pin[dir].pins[0]; 565 566 val2 = pin->amp_step_size * 25; 567 val1 = -1 * (int)pin->amp_offset * (int)val2; 568 #ifdef TLV_DB_SCALE_MUTE 569 val2 |= TLV_DB_SCALE_MUTE; 570 #endif 571 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv)) 572 return -EFAULT; 573 if (put_user(2 * sizeof(unsigned int), tlv + 1)) 574 return -EFAULT; 575 if (put_user(val1, tlv + 2)) 576 return -EFAULT; 577 if (put_user(val2, tlv + 3)) 578 return -EFAULT; 579 return 0; 580 } 581 582 static struct snd_kcontrol_new lola_analog_mixer __devinitdata = { 583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 584 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 585 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 586 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), 587 .info = lola_analog_vol_info, 588 .get = lola_analog_vol_get, 589 .put = lola_analog_vol_put, 590 .tlv.c = lola_analog_vol_tlv, 591 }; 592 593 static int __devinit create_analog_mixer(struct lola *chip, int dir, char *name) 594 { 595 if (!chip->pin[dir].num_pins) 596 return 0; 597 /* no analog volumes on digital only adapters */ 598 if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins) 599 return 0; 600 lola_analog_mixer.name = name; 601 lola_analog_mixer.private_value = dir; 602 return snd_ctl_add(chip->card, 603 snd_ctl_new1(&lola_analog_mixer, chip)); 604 } 605 606 /* 607 * Hardware sample rate converter on digital input 608 */ 609 static int lola_input_src_info(struct snd_kcontrol *kcontrol, 610 struct snd_ctl_elem_info *uinfo) 611 { 612 struct lola *chip = snd_kcontrol_chip(kcontrol); 613 614 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 615 uinfo->count = chip->pin[CAPT].num_pins; 616 uinfo->value.integer.min = 0; 617 uinfo->value.integer.max = 1; 618 return 0; 619 } 620 621 static int lola_input_src_get(struct snd_kcontrol *kcontrol, 622 struct snd_ctl_elem_value *ucontrol) 623 { 624 struct lola *chip = snd_kcontrol_chip(kcontrol); 625 int i; 626 627 for (i = 0; i < chip->pin[CAPT].num_pins; i++) 628 ucontrol->value.integer.value[i] = 629 !!(chip->input_src_mask & (1 << i)); 630 return 0; 631 } 632 633 static int lola_input_src_put(struct snd_kcontrol *kcontrol, 634 struct snd_ctl_elem_value *ucontrol) 635 { 636 struct lola *chip = snd_kcontrol_chip(kcontrol); 637 int i; 638 unsigned int mask; 639 640 mask = 0; 641 for (i = 0; i < chip->pin[CAPT].num_pins; i++) 642 if (ucontrol->value.integer.value[i]) 643 mask |= 1 << i; 644 return lola_set_src_config(chip, mask, true); 645 } 646 647 static struct snd_kcontrol_new lola_input_src_mixer __devinitdata = { 648 .name = "Digital SRC Capture Switch", 649 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 650 .info = lola_input_src_info, 651 .get = lola_input_src_get, 652 .put = lola_input_src_put, 653 }; 654 655 /* 656 * Lola16161 or Lola881 can have Hardware sample rate converters 657 * on its digital input pins 658 */ 659 static int __devinit create_input_src_mixer(struct lola *chip) 660 { 661 if (!chip->input_src_caps_mask) 662 return 0; 663 664 return snd_ctl_add(chip->card, 665 snd_ctl_new1(&lola_input_src_mixer, chip)); 666 } 667 668 /* 669 * src gain mixer 670 */ 671 static int lola_src_gain_info(struct snd_kcontrol *kcontrol, 672 struct snd_ctl_elem_info *uinfo) 673 { 674 unsigned int count = (kcontrol->private_value >> 8) & 0xff; 675 676 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 677 uinfo->count = count; 678 uinfo->value.integer.min = 0; 679 uinfo->value.integer.max = 409; 680 return 0; 681 } 682 683 static int lola_src_gain_get(struct snd_kcontrol *kcontrol, 684 struct snd_ctl_elem_value *ucontrol) 685 { 686 struct lola *chip = snd_kcontrol_chip(kcontrol); 687 unsigned int ofs = kcontrol->private_value & 0xff; 688 unsigned int count = (kcontrol->private_value >> 8) & 0xff; 689 unsigned int mask, i; 690 691 mask = readl(&chip->mixer.array->src_gain_enable); 692 for (i = 0; i < count; i++) { 693 unsigned int idx = ofs + i; 694 unsigned short val; 695 if (!(chip->mixer.src_mask & (1 << idx))) 696 return -EINVAL; 697 if (mask & (1 << idx)) 698 val = readw(&chip->mixer.array->src_gain[idx]) + 1; 699 else 700 val = 0; 701 ucontrol->value.integer.value[i] = val; 702 } 703 return 0; 704 } 705 706 static int lola_src_gain_put(struct snd_kcontrol *kcontrol, 707 struct snd_ctl_elem_value *ucontrol) 708 { 709 struct lola *chip = snd_kcontrol_chip(kcontrol); 710 unsigned int ofs = kcontrol->private_value & 0xff; 711 unsigned int count = (kcontrol->private_value >> 8) & 0xff; 712 int i, err; 713 714 for (i = 0; i < count; i++) { 715 unsigned int idx = ofs + i; 716 unsigned short val = ucontrol->value.integer.value[i]; 717 if (val) 718 val--; 719 err = lola_mixer_set_src_gain(chip, idx, val, !!val); 720 if (err < 0) 721 return err; 722 } 723 return 0; 724 } 725 726 /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */ 727 static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1); 728 729 static struct snd_kcontrol_new lola_src_gain_mixer __devinitdata = { 730 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 731 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 732 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 733 .info = lola_src_gain_info, 734 .get = lola_src_gain_get, 735 .put = lola_src_gain_put, 736 .tlv.p = lola_src_gain_tlv, 737 }; 738 739 static int __devinit create_src_gain_mixer(struct lola *chip, 740 int num, int ofs, char *name) 741 { 742 lola_src_gain_mixer.name = name; 743 lola_src_gain_mixer.private_value = ofs + (num << 8); 744 return snd_ctl_add(chip->card, 745 snd_ctl_new1(&lola_src_gain_mixer, chip)); 746 } 747 748 #if 0 /* not used */ 749 /* 750 * destination gain (matrix-like) mixer 751 */ 752 static int lola_dest_gain_info(struct snd_kcontrol *kcontrol, 753 struct snd_ctl_elem_info *uinfo) 754 { 755 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; 756 757 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 758 uinfo->count = src_num; 759 uinfo->value.integer.min = 0; 760 uinfo->value.integer.max = 433; 761 return 0; 762 } 763 764 static int lola_dest_gain_get(struct snd_kcontrol *kcontrol, 765 struct snd_ctl_elem_value *ucontrol) 766 { 767 struct lola *chip = snd_kcontrol_chip(kcontrol); 768 unsigned int src_ofs = kcontrol->private_value & 0xff; 769 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; 770 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff; 771 unsigned int dst, mask, i; 772 773 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs; 774 mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]); 775 for (i = 0; i < src_num; i++) { 776 unsigned int src = src_ofs + i; 777 unsigned short val; 778 if (!(chip->mixer.src_mask & (1 << src))) 779 return -EINVAL; 780 if (mask & (1 << dst)) 781 val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1; 782 else 783 val = 0; 784 ucontrol->value.integer.value[i] = val; 785 } 786 return 0; 787 } 788 789 static int lola_dest_gain_put(struct snd_kcontrol *kcontrol, 790 struct snd_ctl_elem_value *ucontrol) 791 { 792 struct lola *chip = snd_kcontrol_chip(kcontrol); 793 unsigned int src_ofs = kcontrol->private_value & 0xff; 794 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; 795 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff; 796 unsigned int dst, mask; 797 unsigned short gains[MAX_STREAM_COUNT]; 798 int i, num; 799 800 mask = 0; 801 num = 0; 802 for (i = 0; i < src_num; i++) { 803 unsigned short val = ucontrol->value.integer.value[i]; 804 if (val) { 805 gains[num++] = val - 1; 806 mask |= 1 << i; 807 } 808 } 809 mask <<= src_ofs; 810 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs; 811 return lola_mixer_set_dest_gains(chip, dst, mask, gains); 812 } 813 814 static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1); 815 816 static struct snd_kcontrol_new lola_dest_gain_mixer __devinitdata = { 817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 818 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 819 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 820 .info = lola_dest_gain_info, 821 .get = lola_dest_gain_get, 822 .put = lola_dest_gain_put, 823 .tlv.p = lola_dest_gain_tlv, 824 }; 825 826 static int __devinit create_dest_gain_mixer(struct lola *chip, 827 int src_num, int src_ofs, 828 int num, int ofs, char *name) 829 { 830 lola_dest_gain_mixer.count = num; 831 lola_dest_gain_mixer.name = name; 832 lola_dest_gain_mixer.private_value = 833 src_ofs + (src_num << 8) + (ofs << 16) + (num << 24); 834 return snd_ctl_add(chip->card, 835 snd_ctl_new1(&lola_dest_gain_mixer, chip)); 836 } 837 #endif /* not used */ 838 839 /* 840 */ 841 int __devinit lola_create_mixer(struct lola *chip) 842 { 843 int err; 844 845 err = create_analog_mixer(chip, PLAY, "Analog Playback Volume"); 846 if (err < 0) 847 return err; 848 err = create_analog_mixer(chip, CAPT, "Analog Capture Volume"); 849 if (err < 0) 850 return err; 851 err = create_input_src_mixer(chip); 852 if (err < 0) 853 return err; 854 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0, 855 "Digital Capture Volume"); 856 if (err < 0) 857 return err; 858 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs, 859 chip->mixer.src_stream_out_ofs, 860 "Digital Playback Volume"); 861 if (err < 0) 862 return err; 863 #if 0 864 /* FIXME: buggy mixer matrix handling */ 865 err = create_dest_gain_mixer(chip, 866 chip->mixer.src_phys_ins, 0, 867 chip->mixer.dest_stream_ins, 0, 868 "Line Capture Volume"); 869 if (err < 0) 870 return err; 871 err = create_dest_gain_mixer(chip, 872 chip->mixer.src_stream_outs, 873 chip->mixer.src_stream_out_ofs, 874 chip->mixer.dest_stream_ins, 0, 875 "Stream-Loopback Capture Volume"); 876 if (err < 0) 877 return err; 878 err = create_dest_gain_mixer(chip, 879 chip->mixer.src_phys_ins, 0, 880 chip->mixer.dest_phys_outs, 881 chip->mixer.dest_phys_out_ofs, 882 "Line-Loopback Playback Volume"); 883 if (err < 0) 884 return err; 885 err = create_dest_gain_mixer(chip, 886 chip->mixer.src_stream_outs, 887 chip->mixer.src_stream_out_ofs, 888 chip->mixer.dest_phys_outs, 889 chip->mixer.dest_phys_out_ofs, 890 "Stream Playback Volume"); 891 if (err < 0) 892 return err; 893 #endif /* FIXME */ 894 return init_mixer_values(chip); 895 } 896