Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Support for Digigram Lola PCI-e boards
0004  *
0005  *  Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/init.h>
0010 #include <linux/vmalloc.h>
0011 #include <linux/io.h>
0012 #include <sound/core.h>
0013 #include <sound/control.h>
0014 #include <sound/pcm.h>
0015 #include <sound/tlv.h>
0016 #include "lola.h"
0017 
0018 static int lola_init_pin(struct lola *chip, struct lola_pin *pin,
0019              int dir, int nid)
0020 {
0021     unsigned int val;
0022     int err;
0023 
0024     pin->nid = nid;
0025     err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
0026     if (err < 0) {
0027         dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid);
0028         return err;
0029     }
0030     val &= 0x00f00fff; /* test TYPE and bits 0..11 */
0031     if (val == 0x00400200)    /* Type = 4, Digital = 1 */
0032         pin->is_analog = false;
0033     else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */
0034         pin->is_analog = true;
0035     else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */
0036         pin->is_analog = true;
0037     else {
0038         dev_err(chip->card->dev, "Invalid wcaps 0x%x for 0x%x\n", val, nid);
0039         return -EINVAL;
0040     }
0041 
0042     /* analog parameters only following, so continue in case of Digital pin
0043      */
0044     if (!pin->is_analog)
0045         return 0;
0046 
0047     if (dir == PLAY)
0048         err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val);
0049     else
0050         err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val);
0051     if (err < 0) {
0052         dev_err(chip->card->dev, "Can't read AMP-caps for 0x%x\n", nid);
0053         return err;
0054     }
0055 
0056     pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val);
0057     pin->amp_step_size = LOLA_AMP_STEP_SIZE(val);
0058     pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val);
0059     if (pin->amp_num_steps) {
0060         /* zero as mute state */
0061         pin->amp_num_steps++;
0062         pin->amp_step_size++;
0063     }
0064     pin->amp_offset = LOLA_AMP_OFFSET(val);
0065 
0066     err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val,
0067                   NULL);
0068     if (err < 0) {
0069         dev_err(chip->card->dev, "Can't get MAX_LEVEL 0x%x\n", nid);
0070         return err;
0071     }
0072     pin->max_level = val & 0x3ff;   /* 10 bits */
0073 
0074     pin->config_default_reg = 0;
0075     pin->fixed_gain_list_len = 0;
0076     pin->cur_gain_step = 0;
0077 
0078     return 0;
0079 }
0080 
0081 int lola_init_pins(struct lola *chip, int dir, int *nidp)
0082 {
0083     int i, err, nid;
0084     nid = *nidp;
0085     for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) {
0086         err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid);
0087         if (err < 0)
0088             return err;
0089         if (chip->pin[dir].pins[i].is_analog)
0090             chip->pin[dir].num_analog_pins++;
0091     }
0092     *nidp = nid;
0093     return 0;
0094 }
0095 
0096 void lola_free_mixer(struct lola *chip)
0097 {
0098     vfree(chip->mixer.array_saved);
0099 }
0100 
0101 int lola_init_mixer_widget(struct lola *chip, int nid)
0102 {
0103     unsigned int val;
0104     int err;
0105 
0106     err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
0107     if (err < 0) {
0108         dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid);
0109         return err;
0110     }
0111 
0112     if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */
0113         dev_dbg(chip->card->dev, "No valid mixer widget\n");
0114         return 0;
0115     }
0116 
0117     chip->mixer.nid = nid;
0118     chip->mixer.caps = val;
0119     chip->mixer.array = (struct lola_mixer_array __iomem *)
0120         (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE);
0121 
0122     /* reserve memory to copy mixer data for sleep mode transitions */
0123     chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array));
0124     if (!chip->mixer.array_saved)
0125         return -ENOMEM;
0126 
0127     /* mixer matrix sources are physical input data and play streams */
0128     chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams;
0129     chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins;
0130 
0131     /* mixer matrix destinations are record streams and physical output */
0132     chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
0133     chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
0134 
0135     /* mixer matrix may have unused areas between PhysIn and
0136      * Play or Record and PhysOut zones
0137      */
0138     chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
0139         LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
0140     chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
0141         LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
0142 
0143     /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
0144      * +-+  0-------8------16-------8------16
0145      * | |  |       |       |       |       |
0146      * |s|  | INPUT |       | INPUT |       |
0147      * | |->|  ->   |unused |  ->   |unused |
0148      * |r|  |CAPTURE|       | OUTPUT|       |
0149      * | |  |  MIX  |       |  MIX  |       |
0150      * |c|  8--------------------------------
0151      * | |  |       |       |       |       |
0152      * | |  |       |       |       |       |
0153      * |g|  |unused |unused |unused |unused |
0154      * | |  |       |       |       |       |
0155      * |a|  |       |       |       |       |
0156      * | |  16-------------------------------
0157      * |i|  |       |       |       |       |
0158      * | |  | PLAYBK|       | PLAYBK|       |
0159      * |n|->|  ->   |unused |  ->   |unused |
0160      * | |  |CAPTURE|       | OUTPUT|       |
0161      * | |  |  MIX  |       |  MIX  |       |
0162      * |a|  8--------------------------------
0163      * |r|  |       |       |       |       |
0164      * |r|  |       |       |       |       |
0165      * |a|  |unused |unused |unused |unused |
0166      * |y|  |       |       |       |       |
0167      * | |  |       |       |       |       |
0168      * +++  16--|---------------|------------
0169      *      +---V---------------V-----------+
0170      *      |  dest_mix_gain_enable array   |
0171      *      +-------------------------------+
0172      */
0173     /* example : MixerMatrix of LoLa280
0174      * +-+  0-------8-2
0175      * | |  |       | |
0176      * |s|  | INPUT | |     INPUT
0177      * |r|->|  ->   | |      ->
0178      * |c|  |CAPTURE| | <-  OUTPUT
0179      * | |  |  MIX  | |      MIX
0180      * |g|  8----------
0181      * |a|  |       | |
0182      * |i|  | PLAYBK| |     PLAYBACK
0183      * |n|->|  ->   | |      ->
0184      * | |  |CAPTURE| | <-  OUTPUT
0185      * |a|  |  MIX  | |      MIX
0186      * |r|  8---|----|-
0187      * |r|  +---V----V-------------------+
0188      * |a|  | dest_mix_gain_enable array |
0189      * |y|  +----------------------------+
0190      */
0191     if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
0192         chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
0193         dev_err(chip->card->dev, "Invalid mixer widget size\n");
0194         return -EINVAL;
0195     }
0196 
0197     chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) |
0198         (((1U << chip->mixer.src_stream_outs) - 1)
0199          << chip->mixer.src_stream_out_ofs);
0200     chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) |
0201         (((1U << chip->mixer.dest_phys_outs) - 1)
0202          << chip->mixer.dest_phys_out_ofs);
0203 
0204     dev_dbg(chip->card->dev, "Mixer src_mask=%x, dest_mask=%x\n",
0205             chip->mixer.src_mask, chip->mixer.dest_mask);
0206 
0207     return 0;
0208 }
0209 
0210 static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
0211                    unsigned short gain, bool on)
0212 {
0213     unsigned int oldval, val;
0214 
0215     if (!(chip->mixer.src_mask & (1 << id)))
0216         return -EINVAL;
0217     oldval = val = readl(&chip->mixer.array->src_gain_enable);
0218     if (on)
0219         val |= (1 << id);
0220     else
0221         val &= ~(1 << id);
0222     /* test if values unchanged */
0223     if ((val == oldval) &&
0224         (gain == readw(&chip->mixer.array->src_gain[id])))
0225         return 0;
0226 
0227     dev_dbg(chip->card->dev,
0228         "lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
0229             id, gain, val);
0230     writew(gain, &chip->mixer.array->src_gain[id]);
0231     writel(val, &chip->mixer.array->src_gain_enable);
0232     lola_codec_flush(chip);
0233     /* inform micro-controller about the new source gain */
0234     return lola_codec_write(chip, chip->mixer.nid,
0235                 LOLA_VERB_SET_SOURCE_GAIN, id, 0);
0236 }
0237 
0238 #if 0 /* not used */
0239 static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
0240                     unsigned short *gains)
0241 {
0242     int i;
0243 
0244     if ((chip->mixer.src_mask & mask) != mask)
0245         return -EINVAL;
0246     for (i = 0; i < LOLA_MIXER_DIM; i++) {
0247         if (mask & (1 << i)) {
0248             writew(*gains, &chip->mixer.array->src_gain[i]);
0249             gains++;
0250         }
0251     }
0252     writel(mask, &chip->mixer.array->src_gain_enable);
0253     lola_codec_flush(chip);
0254     if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
0255         /* update for all srcs at once */
0256         return lola_codec_write(chip, chip->mixer.nid,
0257                     LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
0258     }
0259     /* update manually */
0260     for (i = 0; i < LOLA_MIXER_DIM; i++) {
0261         if (mask & (1 << i)) {
0262             lola_codec_write(chip, chip->mixer.nid,
0263                      LOLA_VERB_SET_SOURCE_GAIN, i, 0);
0264         }
0265     }
0266     return 0;
0267 }
0268 #endif /* not used */
0269 
0270 static int lola_mixer_set_mapping_gain(struct lola *chip,
0271                        unsigned int src, unsigned int dest,
0272                        unsigned short gain, bool on)
0273 {
0274     unsigned int val;
0275 
0276     if (!(chip->mixer.src_mask & (1 << src)) ||
0277         !(chip->mixer.dest_mask & (1 << dest)))
0278         return -EINVAL;
0279     if (on)
0280         writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
0281     val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
0282     if (on)
0283         val |= (1 << src);
0284     else
0285         val &= ~(1 << src);
0286     writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
0287     lola_codec_flush(chip);
0288     return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
0289                 src, dest);
0290 }
0291 
0292 #if 0 /* not used */
0293 static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
0294                      unsigned int mask, unsigned short *gains)
0295 {
0296     int i;
0297 
0298     if (!(chip->mixer.dest_mask & (1 << id)) ||
0299         (chip->mixer.src_mask & mask) != mask)
0300         return -EINVAL;
0301     for (i = 0; i < LOLA_MIXER_DIM; i++) {
0302         if (mask & (1 << i)) {
0303             writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
0304             gains++;
0305         }
0306     }
0307     writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
0308     lola_codec_flush(chip);
0309     /* update for all dests at once */
0310     return lola_codec_write(chip, chip->mixer.nid,
0311                 LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
0312 }
0313 #endif /* not used */
0314 
0315 /*
0316  */
0317 
0318 static int set_analog_volume(struct lola *chip, int dir,
0319                  unsigned int idx, unsigned int val,
0320                  bool external_call);
0321 
0322 int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
0323 {
0324     struct lola_pin *pin;
0325     int idx, max_idx;
0326 
0327     pin = chip->pin[dir].pins;
0328     max_idx = chip->pin[dir].num_pins;
0329     for (idx = 0; idx < max_idx; idx++) {
0330         if (pin[idx].is_analog) {
0331             unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
0332             /* set volume and do not save the value */
0333             set_analog_volume(chip, dir, idx, val, false);
0334         }
0335     }
0336     return lola_codec_flush(chip);
0337 }
0338 
0339 void lola_save_mixer(struct lola *chip)
0340 {
0341     /* mute analog output */
0342     if (chip->mixer.array_saved) {
0343         /* store contents of mixer array */
0344         memcpy_fromio(chip->mixer.array_saved, chip->mixer.array,
0345                   sizeof(*chip->mixer.array));
0346     }
0347     lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */
0348 }
0349 
0350 void lola_restore_mixer(struct lola *chip)
0351 {
0352     int i;
0353 
0354     /*lola_reset_setups(chip);*/
0355     if (chip->mixer.array_saved) {
0356         /* restore contents of mixer array */
0357         memcpy_toio(chip->mixer.array, chip->mixer.array_saved,
0358                 sizeof(*chip->mixer.array));
0359         /* inform micro-controller about all restored values
0360          * and ignore return values
0361          */
0362         for (i = 0; i < chip->mixer.src_phys_ins; i++)
0363             lola_codec_write(chip, chip->mixer.nid,
0364                      LOLA_VERB_SET_SOURCE_GAIN,
0365                      i, 0);
0366         for (i = 0; i < chip->mixer.src_stream_outs; i++)
0367             lola_codec_write(chip, chip->mixer.nid,
0368                      LOLA_VERB_SET_SOURCE_GAIN,
0369                      chip->mixer.src_stream_out_ofs + i, 0);
0370         for (i = 0; i < chip->mixer.dest_stream_ins; i++)
0371             lola_codec_write(chip, chip->mixer.nid,
0372                      LOLA_VERB_SET_DESTINATION_GAIN,
0373                      i, 0);
0374         for (i = 0; i < chip->mixer.dest_phys_outs; i++)
0375             lola_codec_write(chip, chip->mixer.nid,
0376                      LOLA_VERB_SET_DESTINATION_GAIN,
0377                      chip->mixer.dest_phys_out_ofs + i, 0);
0378         lola_codec_flush(chip);
0379     }
0380 }
0381 
0382 /*
0383  */
0384 
0385 static int set_analog_volume(struct lola *chip, int dir,
0386                  unsigned int idx, unsigned int val,
0387                  bool external_call)
0388 {
0389     struct lola_pin *pin;
0390     int err;
0391 
0392     if (idx >= chip->pin[dir].num_pins)
0393         return -EINVAL;
0394     pin = &chip->pin[dir].pins[idx];
0395     if (!pin->is_analog || pin->amp_num_steps <= val)
0396         return -EINVAL;
0397     if (external_call && pin->cur_gain_step == val)
0398         return 0;
0399     if (external_call)
0400         lola_codec_flush(chip);
0401     dev_dbg(chip->card->dev,
0402         "set_analog_volume (dir=%d idx=%d, volume=%d)\n",
0403             dir, idx, val);
0404     err = lola_codec_write(chip, pin->nid,
0405                    LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
0406     if (err < 0)
0407         return err;
0408     if (external_call)
0409         pin->cur_gain_step = val;
0410     return 0;
0411 }
0412 
0413 int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
0414 {
0415     int ret = 0;
0416     int success = 0;
0417     int n, err;
0418 
0419     /* SRC can be activated and the dwInputSRCMask is valid? */
0420     if ((chip->input_src_caps_mask & src_mask) != src_mask)
0421         return -EINVAL;
0422     /* handle all even Inputs - SRC is a stereo setting !!! */
0423     for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) {
0424         unsigned int mask = 3U << n; /* handle the stereo case */
0425         unsigned int new_src, src_state;
0426         if (!(chip->input_src_caps_mask & mask))
0427             continue;
0428         /* if one IO needs SRC, both stereo IO will get SRC */
0429         new_src = (src_mask & mask) != 0;
0430         if (update) {
0431             src_state = (chip->input_src_mask & mask) != 0;
0432             if (src_state == new_src)
0433                 continue;   /* nothing to change for this IO */
0434         }
0435         err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid,
0436                        LOLA_VERB_SET_SRC, new_src, 0);
0437         if (!err)
0438             success++;
0439         else
0440             ret = err;
0441     }
0442     if (success)
0443         ret = lola_codec_flush(chip);
0444     if (!ret)
0445         chip->input_src_mask = src_mask;
0446     return ret;
0447 }
0448 
0449 /*
0450  */
0451 static int init_mixer_values(struct lola *chip)
0452 {
0453     int i;
0454 
0455     /* all sample rate converters on */
0456     lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
0457 
0458     /* clear all mixer matrix settings */
0459     memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
0460     /* inform firmware about all updated matrix columns - capture part */
0461     for (i = 0; i < chip->mixer.dest_stream_ins; i++)
0462         lola_codec_write(chip, chip->mixer.nid,
0463                  LOLA_VERB_SET_DESTINATION_GAIN,
0464                  i, 0);
0465     /* inform firmware about all updated matrix columns - output part */
0466     for (i = 0; i < chip->mixer.dest_phys_outs; i++)
0467         lola_codec_write(chip, chip->mixer.nid,
0468                  LOLA_VERB_SET_DESTINATION_GAIN,
0469                  chip->mixer.dest_phys_out_ofs + i, 0);
0470 
0471     /* set all digital input source (master) gains to 0dB */
0472     for (i = 0; i < chip->mixer.src_phys_ins; i++)
0473         lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
0474 
0475     /* set all digital playback source (master) gains to 0dB */
0476     for (i = 0; i < chip->mixer.src_stream_outs; i++)
0477         lola_mixer_set_src_gain(chip,
0478                     i + chip->mixer.src_stream_out_ofs,
0479                     336, true); /* 0dB */
0480     /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
0481     for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
0482         int src = i % chip->mixer.src_phys_ins;
0483         lola_mixer_set_mapping_gain(chip, src, i, 336, true);
0484     }
0485     /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
0486      * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
0487      * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
0488      */
0489     for (i = 0; i < chip->mixer.src_stream_outs; i++) {
0490         int src = chip->mixer.src_stream_out_ofs + i;
0491         int dst = chip->mixer.dest_phys_out_ofs +
0492             i % chip->mixer.dest_phys_outs;
0493         lola_mixer_set_mapping_gain(chip, src, dst, 336, true);
0494     }
0495     return 0;
0496 }
0497 
0498 /*
0499  * analog mixer control element
0500  */
0501 static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
0502                 struct snd_ctl_elem_info *uinfo)
0503 {
0504     struct lola *chip = snd_kcontrol_chip(kcontrol);
0505     int dir = kcontrol->private_value;
0506 
0507     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0508     uinfo->count = chip->pin[dir].num_pins;
0509     uinfo->value.integer.min = 0;
0510     uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps;
0511     return 0;
0512 }
0513 
0514 static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
0515                    struct snd_ctl_elem_value *ucontrol)
0516 {
0517     struct lola *chip = snd_kcontrol_chip(kcontrol);
0518     int dir = kcontrol->private_value;
0519     int i;
0520 
0521     for (i = 0; i < chip->pin[dir].num_pins; i++)
0522         ucontrol->value.integer.value[i] =
0523             chip->pin[dir].pins[i].cur_gain_step;
0524     return 0;
0525 }
0526 
0527 static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
0528                    struct snd_ctl_elem_value *ucontrol)
0529 {
0530     struct lola *chip = snd_kcontrol_chip(kcontrol);
0531     int dir = kcontrol->private_value;
0532     int i, err;
0533 
0534     for (i = 0; i < chip->pin[dir].num_pins; i++) {
0535         err = set_analog_volume(chip, dir, i,
0536                     ucontrol->value.integer.value[i],
0537                     true);
0538         if (err < 0)
0539             return err;
0540     }
0541     return 0;
0542 }
0543 
0544 static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
0545                    unsigned int size, unsigned int __user *tlv)
0546 {
0547     struct lola *chip = snd_kcontrol_chip(kcontrol);
0548     int dir = kcontrol->private_value;
0549     unsigned int val1, val2;
0550     struct lola_pin *pin;
0551 
0552     if (size < 4 * sizeof(unsigned int))
0553         return -ENOMEM;
0554     pin = &chip->pin[dir].pins[0];
0555 
0556     val2 = pin->amp_step_size * 25;
0557     val1 = -1 * (int)pin->amp_offset * (int)val2;
0558 #ifdef TLV_DB_SCALE_MUTE
0559     val2 |= TLV_DB_SCALE_MUTE;
0560 #endif
0561     if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv))
0562         return -EFAULT;
0563     if (put_user(2 * sizeof(unsigned int), tlv + 1))
0564         return -EFAULT;
0565     if (put_user(val1, tlv + 2))
0566         return -EFAULT;
0567     if (put_user(val2, tlv + 3))
0568         return -EFAULT;
0569     return 0;
0570 }
0571 
0572 static struct snd_kcontrol_new lola_analog_mixer = {
0573     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0574     .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0575            SNDRV_CTL_ELEM_ACCESS_TLV_READ |
0576            SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
0577     .info = lola_analog_vol_info,
0578     .get = lola_analog_vol_get,
0579     .put = lola_analog_vol_put,
0580     .tlv.c = lola_analog_vol_tlv,
0581 };
0582 
0583 static int create_analog_mixer(struct lola *chip, int dir, char *name)
0584 {
0585     if (!chip->pin[dir].num_pins)
0586         return 0;
0587     /* no analog volumes on digital only adapters */
0588     if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins)
0589         return 0;
0590     lola_analog_mixer.name = name;
0591     lola_analog_mixer.private_value = dir;
0592     return snd_ctl_add(chip->card,
0593                snd_ctl_new1(&lola_analog_mixer, chip));
0594 }
0595 
0596 /*
0597  * Hardware sample rate converter on digital input
0598  */
0599 static int lola_input_src_info(struct snd_kcontrol *kcontrol,
0600                    struct snd_ctl_elem_info *uinfo)
0601 {
0602     struct lola *chip = snd_kcontrol_chip(kcontrol);
0603 
0604     uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
0605     uinfo->count = chip->pin[CAPT].num_pins;
0606     uinfo->value.integer.min = 0;
0607     uinfo->value.integer.max = 1;
0608     return 0;
0609 }
0610 
0611 static int lola_input_src_get(struct snd_kcontrol *kcontrol,
0612                   struct snd_ctl_elem_value *ucontrol)
0613 {
0614     struct lola *chip = snd_kcontrol_chip(kcontrol);
0615     int i;
0616 
0617     for (i = 0; i < chip->pin[CAPT].num_pins; i++)
0618         ucontrol->value.integer.value[i] =
0619             !!(chip->input_src_mask & (1 << i));
0620     return 0;
0621 }
0622 
0623 static int lola_input_src_put(struct snd_kcontrol *kcontrol,
0624                   struct snd_ctl_elem_value *ucontrol)
0625 {
0626     struct lola *chip = snd_kcontrol_chip(kcontrol);
0627     int i;
0628     unsigned int mask;
0629 
0630     mask = 0;
0631     for (i = 0; i < chip->pin[CAPT].num_pins; i++)
0632         if (ucontrol->value.integer.value[i])
0633             mask |= 1 << i;
0634     return lola_set_src_config(chip, mask, true);
0635 }
0636 
0637 static const struct snd_kcontrol_new lola_input_src_mixer = {
0638     .name = "Digital SRC Capture Switch",
0639     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0640     .info = lola_input_src_info,
0641     .get = lola_input_src_get,
0642     .put = lola_input_src_put,
0643 };
0644 
0645 /*
0646  * Lola16161 or Lola881 can have Hardware sample rate converters
0647  * on its digital input pins
0648  */
0649 static int create_input_src_mixer(struct lola *chip)
0650 {
0651     if (!chip->input_src_caps_mask)
0652         return 0;
0653 
0654     return snd_ctl_add(chip->card,
0655                snd_ctl_new1(&lola_input_src_mixer, chip));
0656 }
0657 
0658 /*
0659  * src gain mixer
0660  */
0661 static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
0662                   struct snd_ctl_elem_info *uinfo)
0663 {
0664     unsigned int count = (kcontrol->private_value >> 8) & 0xff;
0665 
0666     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0667     uinfo->count = count;
0668     uinfo->value.integer.min = 0;
0669     uinfo->value.integer.max = 409;
0670     return 0;
0671 }
0672 
0673 static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
0674                  struct snd_ctl_elem_value *ucontrol)
0675 {
0676     struct lola *chip = snd_kcontrol_chip(kcontrol);
0677     unsigned int ofs = kcontrol->private_value & 0xff;
0678     unsigned int count = (kcontrol->private_value >> 8) & 0xff;
0679     unsigned int mask, i;
0680 
0681     mask = readl(&chip->mixer.array->src_gain_enable);
0682     for (i = 0; i < count; i++) {
0683         unsigned int idx = ofs + i;
0684         unsigned short val;
0685         if (!(chip->mixer.src_mask & (1 << idx)))
0686             return -EINVAL;
0687         if (mask & (1 << idx))
0688             val = readw(&chip->mixer.array->src_gain[idx]) + 1;
0689         else
0690             val = 0;
0691         ucontrol->value.integer.value[i] = val;
0692     }
0693     return 0;
0694 }
0695 
0696 static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
0697                  struct snd_ctl_elem_value *ucontrol)
0698 {
0699     struct lola *chip = snd_kcontrol_chip(kcontrol);
0700     unsigned int ofs = kcontrol->private_value & 0xff;
0701     unsigned int count = (kcontrol->private_value >> 8) & 0xff;
0702     int i, err;
0703 
0704     for (i = 0; i < count; i++) {
0705         unsigned int idx = ofs + i;
0706         unsigned short val = ucontrol->value.integer.value[i];
0707         if (val)
0708             val--;
0709         err = lola_mixer_set_src_gain(chip, idx, val, !!val);
0710         if (err < 0)
0711             return err;
0712     }
0713     return 0;
0714 }
0715 
0716 /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
0717 static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
0718 
0719 static struct snd_kcontrol_new lola_src_gain_mixer = {
0720     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0721     .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0722            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0723     .info = lola_src_gain_info,
0724     .get = lola_src_gain_get,
0725     .put = lola_src_gain_put,
0726     .tlv.p = lola_src_gain_tlv,
0727 };
0728 
0729 static int create_src_gain_mixer(struct lola *chip,
0730                  int num, int ofs, char *name)
0731 {
0732     lola_src_gain_mixer.name = name;
0733     lola_src_gain_mixer.private_value = ofs + (num << 8);
0734     return snd_ctl_add(chip->card,
0735                snd_ctl_new1(&lola_src_gain_mixer, chip));
0736 }
0737 
0738 #if 0 /* not used */
0739 /*
0740  * destination gain (matrix-like) mixer
0741  */
0742 static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
0743                    struct snd_ctl_elem_info *uinfo)
0744 {
0745     unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
0746 
0747     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0748     uinfo->count = src_num;
0749     uinfo->value.integer.min = 0;
0750     uinfo->value.integer.max = 433;
0751     return 0;
0752 }
0753 
0754 static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
0755                   struct snd_ctl_elem_value *ucontrol)
0756 {
0757     struct lola *chip = snd_kcontrol_chip(kcontrol);
0758     unsigned int src_ofs = kcontrol->private_value & 0xff;
0759     unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
0760     unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
0761     unsigned int dst, mask, i;
0762 
0763     dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
0764     mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
0765     for (i = 0; i < src_num; i++) {
0766         unsigned int src = src_ofs + i;
0767         unsigned short val;
0768         if (!(chip->mixer.src_mask & (1 << src)))
0769             return -EINVAL;
0770         if (mask & (1 << dst))
0771             val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
0772         else
0773             val = 0;
0774         ucontrol->value.integer.value[i] = val;
0775     }
0776     return 0;
0777 }
0778 
0779 static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
0780                   struct snd_ctl_elem_value *ucontrol)
0781 {
0782     struct lola *chip = snd_kcontrol_chip(kcontrol);
0783     unsigned int src_ofs = kcontrol->private_value & 0xff;
0784     unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
0785     unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
0786     unsigned int dst, mask;
0787     unsigned short gains[MAX_STREAM_COUNT];
0788     int i, num;
0789 
0790     mask = 0;
0791     num = 0;
0792     for (i = 0; i < src_num; i++) {
0793         unsigned short val = ucontrol->value.integer.value[i];
0794         if (val) {
0795             gains[num++] = val - 1;
0796             mask |= 1 << i;
0797         }
0798     }
0799     mask <<= src_ofs;
0800     dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
0801     return lola_mixer_set_dest_gains(chip, dst, mask, gains);
0802 }
0803 
0804 static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
0805 
0806 static struct snd_kcontrol_new lola_dest_gain_mixer = {
0807     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0808     .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0809            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0810     .info = lola_dest_gain_info,
0811     .get = lola_dest_gain_get,
0812     .put = lola_dest_gain_put,
0813     .tlv.p = lola_dest_gain_tlv,
0814 };
0815 
0816 static int create_dest_gain_mixer(struct lola *chip,
0817                   int src_num, int src_ofs,
0818                   int num, int ofs, char *name)
0819 {
0820     lola_dest_gain_mixer.count = num;
0821     lola_dest_gain_mixer.name = name;
0822     lola_dest_gain_mixer.private_value =
0823         src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
0824     return snd_ctl_add(chip->card,
0825               snd_ctl_new1(&lola_dest_gain_mixer, chip));
0826 }
0827 #endif /* not used */
0828 
0829 /*
0830  */
0831 int lola_create_mixer(struct lola *chip)
0832 {
0833     int err;
0834 
0835     err = create_analog_mixer(chip, PLAY, "Analog Playback Volume");
0836     if (err < 0)
0837         return err;
0838     err = create_analog_mixer(chip, CAPT, "Analog Capture Volume");
0839     if (err < 0)
0840         return err;
0841     err = create_input_src_mixer(chip);
0842     if (err < 0)
0843         return err;
0844     err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
0845                     "Digital Capture Volume");
0846     if (err < 0)
0847         return err;
0848     err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
0849                     chip->mixer.src_stream_out_ofs,
0850                     "Digital Playback Volume");
0851     if (err < 0)
0852         return err;
0853 #if 0
0854 /* FIXME: buggy mixer matrix handling */
0855     err = create_dest_gain_mixer(chip,
0856                      chip->mixer.src_phys_ins, 0,
0857                      chip->mixer.dest_stream_ins, 0,
0858                      "Line Capture Volume");
0859     if (err < 0)
0860         return err;
0861     err = create_dest_gain_mixer(chip,
0862                      chip->mixer.src_stream_outs,
0863                      chip->mixer.src_stream_out_ofs,
0864                      chip->mixer.dest_stream_ins, 0,
0865                      "Stream-Loopback Capture Volume");
0866     if (err < 0)
0867         return err;
0868     err = create_dest_gain_mixer(chip,
0869                      chip->mixer.src_phys_ins, 0,
0870                      chip->mixer.dest_phys_outs,
0871                      chip->mixer.dest_phys_out_ofs,
0872                      "Line-Loopback Playback Volume");
0873     if (err < 0)
0874         return err;
0875     err = create_dest_gain_mixer(chip,
0876                      chip->mixer.src_stream_outs,
0877                      chip->mixer.src_stream_out_ofs,
0878                      chip->mixer.dest_phys_outs,
0879                      chip->mixer.dest_phys_out_ofs,
0880                      "Stream Playback Volume");
0881     if (err < 0)
0882         return err;
0883 #endif /* FIXME */
0884     return init_mixer_values(chip);
0885 }