Lines Matching +full:pin +full:- +full:val
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Support for Digigram Lola PCI-e boards
18 static int lola_init_pin(struct lola *chip, struct lola_pin *pin, in lola_init_pin() argument
21 unsigned int val; in lola_init_pin() local
24 pin->nid = nid; in lola_init_pin()
25 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); in lola_init_pin()
27 dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid); in lola_init_pin()
30 val &= 0x00f00fff; /* test TYPE and bits 0..11 */ in lola_init_pin()
31 if (val == 0x00400200) /* Type = 4, Digital = 1 */ in lola_init_pin()
32 pin->is_analog = false; in lola_init_pin()
33 else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */ in lola_init_pin()
34 pin->is_analog = true; in lola_init_pin()
35 else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */ in lola_init_pin()
36 pin->is_analog = true; in lola_init_pin()
38 dev_err(chip->card->dev, "Invalid wcaps 0x%x for 0x%x\n", val, nid); in lola_init_pin()
39 return -EINVAL; in lola_init_pin()
42 /* analog parameters only following, so continue in case of Digital pin in lola_init_pin()
44 if (!pin->is_analog) in lola_init_pin()
48 err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val); in lola_init_pin()
50 err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val); in lola_init_pin()
52 dev_err(chip->card->dev, "Can't read AMP-caps for 0x%x\n", nid); in lola_init_pin()
56 pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val); in lola_init_pin()
57 pin->amp_step_size = LOLA_AMP_STEP_SIZE(val); in lola_init_pin()
58 pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val); in lola_init_pin()
59 if (pin->amp_num_steps) { in lola_init_pin()
61 pin->amp_num_steps++; in lola_init_pin()
62 pin->amp_step_size++; in lola_init_pin()
64 pin->amp_offset = LOLA_AMP_OFFSET(val); in lola_init_pin()
66 err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, in lola_init_pin()
69 dev_err(chip->card->dev, "Can't get MAX_LEVEL 0x%x\n", nid); in lola_init_pin()
72 pin->max_level = val & 0x3ff; /* 10 bits */ in lola_init_pin()
74 pin->config_default_reg = 0; in lola_init_pin()
75 pin->fixed_gain_list_len = 0; in lola_init_pin()
76 pin->cur_gain_step = 0; in lola_init_pin()
85 for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) { in lola_init_pins()
86 err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid); in lola_init_pins()
89 if (chip->pin[dir].pins[i].is_analog) in lola_init_pins()
90 chip->pin[dir].num_analog_pins++; in lola_init_pins()
98 vfree(chip->mixer.array_saved); in lola_free_mixer()
103 unsigned int val; in lola_init_mixer_widget() local
106 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); in lola_init_mixer_widget()
108 dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid); in lola_init_mixer_widget()
112 if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */ in lola_init_mixer_widget()
113 dev_dbg(chip->card->dev, "No valid mixer widget\n"); in lola_init_mixer_widget()
117 chip->mixer.nid = nid; in lola_init_mixer_widget()
118 chip->mixer.caps = val; in lola_init_mixer_widget()
119 chip->mixer.array = (struct lola_mixer_array __iomem *) in lola_init_mixer_widget()
120 (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE); in lola_init_mixer_widget()
123 chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array)); in lola_init_mixer_widget()
124 if (!chip->mixer.array_saved) in lola_init_mixer_widget()
125 return -ENOMEM; in lola_init_mixer_widget()
128 chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams; in lola_init_mixer_widget()
129 chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins; in lola_init_mixer_widget()
132 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams; in lola_init_mixer_widget()
133 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins; in lola_init_mixer_widget()
138 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins + in lola_init_mixer_widget()
139 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val); in lola_init_mixer_widget()
140 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins + in lola_init_mixer_widget()
141 LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val); in lola_init_mixer_widget()
144 * +-+ 0-------8------16-------8------16 in lola_init_mixer_widget()
147 * | |->| -> |unused | -> |unused | in lola_init_mixer_widget()
150 * |c| 8-------------------------------- in lola_init_mixer_widget()
156 * | | 16------------------------------- in lola_init_mixer_widget()
159 * |n|->| -> |unused | -> |unused | in lola_init_mixer_widget()
162 * |a| 8-------------------------------- in lola_init_mixer_widget()
168 * +++ 16--|---------------|------------ in lola_init_mixer_widget()
169 * +---V---------------V-----------+ in lola_init_mixer_widget()
171 * +-------------------------------+ in lola_init_mixer_widget()
174 * +-+ 0-------8-2 in lola_init_mixer_widget()
177 * |r|->| -> | | -> in lola_init_mixer_widget()
178 * |c| |CAPTURE| | <- OUTPUT in lola_init_mixer_widget()
180 * |g| 8---------- in lola_init_mixer_widget()
183 * |n|->| -> | | -> in lola_init_mixer_widget()
184 * | | |CAPTURE| | <- OUTPUT in lola_init_mixer_widget()
186 * |r| 8---|----|- in lola_init_mixer_widget()
187 * |r| +---V----V-------------------+ in lola_init_mixer_widget()
189 * |y| +----------------------------+ in lola_init_mixer_widget()
191 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT || in lola_init_mixer_widget()
192 chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) { in lola_init_mixer_widget()
193 dev_err(chip->card->dev, "Invalid mixer widget size\n"); in lola_init_mixer_widget()
194 return -EINVAL; in lola_init_mixer_widget()
197 chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) | in lola_init_mixer_widget()
198 (((1U << chip->mixer.src_stream_outs) - 1) in lola_init_mixer_widget()
199 << chip->mixer.src_stream_out_ofs); in lola_init_mixer_widget()
200 chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) | in lola_init_mixer_widget()
201 (((1U << chip->mixer.dest_phys_outs) - 1) in lola_init_mixer_widget()
202 << chip->mixer.dest_phys_out_ofs); in lola_init_mixer_widget()
204 dev_dbg(chip->card->dev, "Mixer src_mask=%x, dest_mask=%x\n", in lola_init_mixer_widget()
205 chip->mixer.src_mask, chip->mixer.dest_mask); in lola_init_mixer_widget()
213 unsigned int oldval, val; in lola_mixer_set_src_gain() local
215 if (!(chip->mixer.src_mask & (1 << id))) in lola_mixer_set_src_gain()
216 return -EINVAL; in lola_mixer_set_src_gain()
217 oldval = val = readl(&chip->mixer.array->src_gain_enable); in lola_mixer_set_src_gain()
219 val |= (1 << id); in lola_mixer_set_src_gain()
221 val &= ~(1 << id); in lola_mixer_set_src_gain()
223 if ((val == oldval) && in lola_mixer_set_src_gain()
224 (gain == readw(&chip->mixer.array->src_gain[id]))) in lola_mixer_set_src_gain()
227 dev_dbg(chip->card->dev, in lola_mixer_set_src_gain()
229 id, gain, val); in lola_mixer_set_src_gain()
230 writew(gain, &chip->mixer.array->src_gain[id]); in lola_mixer_set_src_gain()
231 writel(val, &chip->mixer.array->src_gain_enable); in lola_mixer_set_src_gain()
233 /* inform micro-controller about the new source gain */ in lola_mixer_set_src_gain()
234 return lola_codec_write(chip, chip->mixer.nid, in lola_mixer_set_src_gain()
244 if ((chip->mixer.src_mask & mask) != mask)
245 return -EINVAL;
248 writew(*gains, &chip->mixer.array->src_gain[i]);
252 writel(mask, &chip->mixer.array->src_gain_enable);
254 if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
256 return lola_codec_write(chip, chip->mixer.nid,
262 lola_codec_write(chip, chip->mixer.nid,
274 unsigned int val; in lola_mixer_set_mapping_gain() local
276 if (!(chip->mixer.src_mask & (1 << src)) || in lola_mixer_set_mapping_gain()
277 !(chip->mixer.dest_mask & (1 << dest))) in lola_mixer_set_mapping_gain()
278 return -EINVAL; in lola_mixer_set_mapping_gain()
280 writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]); in lola_mixer_set_mapping_gain()
281 val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]); in lola_mixer_set_mapping_gain()
283 val |= (1 << src); in lola_mixer_set_mapping_gain()
285 val &= ~(1 << src); in lola_mixer_set_mapping_gain()
286 writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]); in lola_mixer_set_mapping_gain()
288 return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN, in lola_mixer_set_mapping_gain()
298 if (!(chip->mixer.dest_mask & (1 << id)) ||
299 (chip->mixer.src_mask & mask) != mask)
300 return -EINVAL;
303 writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
307 writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
310 return lola_codec_write(chip, chip->mixer.nid,
319 unsigned int idx, unsigned int val,
324 struct lola_pin *pin; in lola_setup_all_analog_gains() local
327 pin = chip->pin[dir].pins; in lola_setup_all_analog_gains()
328 max_idx = chip->pin[dir].num_pins; in lola_setup_all_analog_gains()
330 if (pin[idx].is_analog) { in lola_setup_all_analog_gains()
331 unsigned int val = mute ? 0 : pin[idx].cur_gain_step; in lola_setup_all_analog_gains() local
333 set_analog_volume(chip, dir, idx, val, false); in lola_setup_all_analog_gains()
342 if (chip->mixer.array_saved) { in lola_save_mixer()
344 memcpy_fromio(chip->mixer.array_saved, chip->mixer.array, in lola_save_mixer()
345 sizeof(*chip->mixer.array)); in lola_save_mixer()
355 if (chip->mixer.array_saved) { in lola_restore_mixer()
357 memcpy_toio(chip->mixer.array, chip->mixer.array_saved, in lola_restore_mixer()
358 sizeof(*chip->mixer.array)); in lola_restore_mixer()
359 /* inform micro-controller about all restored values in lola_restore_mixer()
362 for (i = 0; i < chip->mixer.src_phys_ins; i++) in lola_restore_mixer()
363 lola_codec_write(chip, chip->mixer.nid, in lola_restore_mixer()
366 for (i = 0; i < chip->mixer.src_stream_outs; i++) in lola_restore_mixer()
367 lola_codec_write(chip, chip->mixer.nid, in lola_restore_mixer()
369 chip->mixer.src_stream_out_ofs + i, 0); in lola_restore_mixer()
370 for (i = 0; i < chip->mixer.dest_stream_ins; i++) in lola_restore_mixer()
371 lola_codec_write(chip, chip->mixer.nid, in lola_restore_mixer()
374 for (i = 0; i < chip->mixer.dest_phys_outs; i++) in lola_restore_mixer()
375 lola_codec_write(chip, chip->mixer.nid, in lola_restore_mixer()
377 chip->mixer.dest_phys_out_ofs + i, 0); in lola_restore_mixer()
386 unsigned int idx, unsigned int val, in set_analog_volume() argument
389 struct lola_pin *pin; in set_analog_volume() local
392 if (idx >= chip->pin[dir].num_pins) in set_analog_volume()
393 return -EINVAL; in set_analog_volume()
394 pin = &chip->pin[dir].pins[idx]; in set_analog_volume()
395 if (!pin->is_analog || pin->amp_num_steps <= val) in set_analog_volume()
396 return -EINVAL; in set_analog_volume()
397 if (external_call && pin->cur_gain_step == val) in set_analog_volume()
401 dev_dbg(chip->card->dev, in set_analog_volume()
403 dir, idx, val); in set_analog_volume()
404 err = lola_codec_write(chip, pin->nid, in set_analog_volume()
405 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0); in set_analog_volume()
409 pin->cur_gain_step = val; in set_analog_volume()
420 if ((chip->input_src_caps_mask & src_mask) != src_mask) in lola_set_src_config()
421 return -EINVAL; in lola_set_src_config()
422 /* handle all even Inputs - SRC is a stereo setting !!! */ in lola_set_src_config()
423 for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) { in lola_set_src_config()
426 if (!(chip->input_src_caps_mask & mask)) in lola_set_src_config()
431 src_state = (chip->input_src_mask & mask) != 0; in lola_set_src_config()
435 err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid, in lola_set_src_config()
445 chip->input_src_mask = src_mask; in lola_set_src_config()
456 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false); in init_mixer_values()
459 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array)); in init_mixer_values()
460 /* inform firmware about all updated matrix columns - capture part */ in init_mixer_values()
461 for (i = 0; i < chip->mixer.dest_stream_ins; i++) in init_mixer_values()
462 lola_codec_write(chip, chip->mixer.nid, in init_mixer_values()
465 /* inform firmware about all updated matrix columns - output part */ in init_mixer_values()
466 for (i = 0; i < chip->mixer.dest_phys_outs; i++) in init_mixer_values()
467 lola_codec_write(chip, chip->mixer.nid, in init_mixer_values()
469 chip->mixer.dest_phys_out_ofs + i, 0); in init_mixer_values()
472 for (i = 0; i < chip->mixer.src_phys_ins; i++) in init_mixer_values()
476 for (i = 0; i < chip->mixer.src_stream_outs; i++) in init_mixer_values()
478 i + chip->mixer.src_stream_out_ofs, in init_mixer_values()
480 /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */ in init_mixer_values()
481 for (i = 0; i < chip->mixer.dest_stream_ins; i++) { in init_mixer_values()
482 int src = i % chip->mixer.src_phys_ins; in init_mixer_values()
485 /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT in init_mixer_values()
489 for (i = 0; i < chip->mixer.src_stream_outs; i++) { in init_mixer_values()
490 int src = chip->mixer.src_stream_out_ofs + i; in init_mixer_values()
491 int dst = chip->mixer.dest_phys_out_ofs + in init_mixer_values()
492 i % chip->mixer.dest_phys_outs; in init_mixer_values()
505 int dir = kcontrol->private_value; in lola_analog_vol_info()
507 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in lola_analog_vol_info()
508 uinfo->count = chip->pin[dir].num_pins; in lola_analog_vol_info()
509 uinfo->value.integer.min = 0; in lola_analog_vol_info()
510 uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps; in lola_analog_vol_info()
518 int dir = kcontrol->private_value; in lola_analog_vol_get()
521 for (i = 0; i < chip->pin[dir].num_pins; i++) in lola_analog_vol_get()
522 ucontrol->value.integer.value[i] = in lola_analog_vol_get()
523 chip->pin[dir].pins[i].cur_gain_step; in lola_analog_vol_get()
531 int dir = kcontrol->private_value; in lola_analog_vol_put()
534 for (i = 0; i < chip->pin[dir].num_pins; i++) { in lola_analog_vol_put()
536 ucontrol->value.integer.value[i], in lola_analog_vol_put()
548 int dir = kcontrol->private_value; in lola_analog_vol_tlv()
550 struct lola_pin *pin; in lola_analog_vol_tlv() local
553 return -ENOMEM; in lola_analog_vol_tlv()
554 pin = &chip->pin[dir].pins[0]; in lola_analog_vol_tlv()
556 val2 = pin->amp_step_size * 25; in lola_analog_vol_tlv()
557 val1 = -1 * (int)pin->amp_offset * (int)val2; in lola_analog_vol_tlv()
562 return -EFAULT; in lola_analog_vol_tlv()
564 return -EFAULT; in lola_analog_vol_tlv()
566 return -EFAULT; in lola_analog_vol_tlv()
568 return -EFAULT; in lola_analog_vol_tlv()
585 if (!chip->pin[dir].num_pins) in create_analog_mixer()
588 if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins) in create_analog_mixer()
592 return snd_ctl_add(chip->card, in create_analog_mixer()
604 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in lola_input_src_info()
605 uinfo->count = chip->pin[CAPT].num_pins; in lola_input_src_info()
606 uinfo->value.integer.min = 0; in lola_input_src_info()
607 uinfo->value.integer.max = 1; in lola_input_src_info()
617 for (i = 0; i < chip->pin[CAPT].num_pins; i++) in lola_input_src_get()
618 ucontrol->value.integer.value[i] = in lola_input_src_get()
619 !!(chip->input_src_mask & (1 << i)); in lola_input_src_get()
631 for (i = 0; i < chip->pin[CAPT].num_pins; i++) in lola_input_src_put()
632 if (ucontrol->value.integer.value[i]) in lola_input_src_put()
651 if (!chip->input_src_caps_mask) in create_input_src_mixer()
654 return snd_ctl_add(chip->card, in create_input_src_mixer()
664 unsigned int count = (kcontrol->private_value >> 8) & 0xff; in lola_src_gain_info()
666 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in lola_src_gain_info()
667 uinfo->count = count; in lola_src_gain_info()
668 uinfo->value.integer.min = 0; in lola_src_gain_info()
669 uinfo->value.integer.max = 409; in lola_src_gain_info()
677 unsigned int ofs = kcontrol->private_value & 0xff; in lola_src_gain_get()
678 unsigned int count = (kcontrol->private_value >> 8) & 0xff; in lola_src_gain_get()
681 mask = readl(&chip->mixer.array->src_gain_enable); in lola_src_gain_get()
684 unsigned short val; in lola_src_gain_get() local
685 if (!(chip->mixer.src_mask & (1 << idx))) in lola_src_gain_get()
686 return -EINVAL; in lola_src_gain_get()
688 val = readw(&chip->mixer.array->src_gain[idx]) + 1; in lola_src_gain_get()
690 val = 0; in lola_src_gain_get()
691 ucontrol->value.integer.value[i] = val; in lola_src_gain_get()
700 unsigned int ofs = kcontrol->private_value & 0xff; in lola_src_gain_put()
701 unsigned int count = (kcontrol->private_value >> 8) & 0xff; in lola_src_gain_put()
706 unsigned short val = ucontrol->value.integer.value[i]; in lola_src_gain_put() local
707 if (val) in lola_src_gain_put()
708 val--; in lola_src_gain_put()
709 err = lola_mixer_set_src_gain(chip, idx, val, !!val); in lola_src_gain_put()
716 /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
717 static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
734 return snd_ctl_add(chip->card, in create_src_gain_mixer()
740 * destination gain (matrix-like) mixer
745 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
747 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
748 uinfo->count = src_num;
749 uinfo->value.integer.min = 0;
750 uinfo->value.integer.max = 433;
758 unsigned int src_ofs = kcontrol->private_value & 0xff;
759 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
760 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
763 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
764 mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
767 unsigned short val;
768 if (!(chip->mixer.src_mask & (1 << src)))
769 return -EINVAL;
771 val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
773 val = 0;
774 ucontrol->value.integer.value[i] = val;
783 unsigned int src_ofs = kcontrol->private_value & 0xff;
784 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
785 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
793 unsigned short val = ucontrol->value.integer.value[i];
794 if (val) {
795 gains[num++] = val - 1;
800 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
804 static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
824 return snd_ctl_add(chip->card,
844 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0, in lola_create_mixer()
848 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs, in lola_create_mixer()
849 chip->mixer.src_stream_out_ofs, in lola_create_mixer()
856 chip->mixer.src_phys_ins, 0, in lola_create_mixer()
857 chip->mixer.dest_stream_ins, 0, in lola_create_mixer()
862 chip->mixer.src_stream_outs, in lola_create_mixer()
863 chip->mixer.src_stream_out_ofs, in lola_create_mixer()
864 chip->mixer.dest_stream_ins, 0, in lola_create_mixer()
865 "Stream-Loopback Capture Volume"); in lola_create_mixer()
869 chip->mixer.src_phys_ins, 0, in lola_create_mixer()
870 chip->mixer.dest_phys_outs, in lola_create_mixer()
871 chip->mixer.dest_phys_out_ofs, in lola_create_mixer()
872 "Line-Loopback Playback Volume"); in lola_create_mixer()
876 chip->mixer.src_stream_outs, in lola_create_mixer()
877 chip->mixer.src_stream_out_ofs, in lola_create_mixer()
878 chip->mixer.dest_phys_outs, in lola_create_mixer()
879 chip->mixer.dest_phys_out_ofs, in lola_create_mixer()