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