ALSA: lola - Fix for Lola280 board
authorMarkus Bollinger <bollinger@digigram.com>
Fri, 24 Jun 2011 10:54:43 +0000 (12:54 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 24 Jun 2011 10:54:43 +0000 (12:54 +0200)
- add/fix comments and debug messages
- fix incomplete matrix init
- comment out creation of buggy lola_dest_gain_mixer controls
- minor optimisations

Signed-off-by: Markus Bollinger <bollinger@digigram.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/lola/lola.h
sound/pci/lola/lola_mixer.c

index d5708e29b16df9b11831214d3be84b348e10ba3c..f0b100059efde7df820e516f199ebffcd9e4d350 100644 (file)
@@ -480,7 +480,7 @@ struct lola {
 
 /* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
 #define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res)   ((res >> 2) & 0x1f)
-#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res)  ((res >> 7) & 0x1f)
+#define LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(res)  ((res >> 7) & 0x1f)
 
 int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
                     unsigned int data, unsigned int extdata);
index 5d518f1a712cf1d87503f0e26619645cc2ca8262..6b8d64812951a1c15626ef9ed37c731ee9dad502 100644 (file)
@@ -144,40 +144,61 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
        chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
        chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
 
-       /* mixer matrix can have unused areas between PhysIn and
+       /* mixer matrix may have unused areas between PhysIn and
         * Play or Record and PhysOut zones
         */
        chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
                LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
        chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
-               LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val);
-
-       /* example : MixerMatrix of LoLa881
-        * 0-------8------16-------8------16
-        * |       |       |       |       |
-        * | INPUT |       | INPUT |       |
-        * | ->    |unused | ->    |unused |
-        * | RECORD|       | OUTPUT|       |
-        * |       |       |       |       |
-        * 8--------------------------------
-        * |       |       |       |       |
-        * |       |       |       |       |
-        * |unused |unused |unused |unused |
-        * |       |       |       |       |
-        * |       |       |       |       |
-        * 16-------------------------------
-        * |       |       |       |       |
-        * | PLAY  |       | PLAY  |       |
-        * |  ->   |unused | ->    |unused |
-        * | RECORD|       | OUTPUT|       |
-        * |       |       |       |       |
-        * 8--------------------------------
-        * |       |       |       |       |
-        * |       |       |       |       |
-        * |unused |unused |unused |unused |
-        * |       |       |       |       |
-        * |       |       |       |       |
-        * 16-------------------------------
+               LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
+
+       /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
+        * +-+  0-------8------16-------8------16
+        * | |  |       |       |       |       |
+        * |s|  | INPUT |       | INPUT |       |
+        * | |->|  ->   |unused |  ->   |unused |
+        * |r|  |CAPTURE|       | OUTPUT|       |
+        * | |  |  MIX  |       |  MIX  |       |
+        * |c|  8--------------------------------
+        * | |  |       |       |       |       |
+        * | |  |       |       |       |       |
+        * |g|  |unused |unused |unused |unused |
+        * | |  |       |       |       |       |
+        * |a|  |       |       |       |       |
+        * | |  16-------------------------------
+        * |i|  |       |       |       |       |
+        * | |  | PLAYBK|       | PLAYBK|       |
+        * |n|->|  ->   |unused |  ->   |unused |
+        * | |  |CAPTURE|       | OUTPUT|       |
+        * | |  |  MIX  |       |  MIX  |       |
+        * |a|  8--------------------------------
+        * |r|  |       |       |       |       |
+        * |r|  |       |       |       |       |
+        * |a|  |unused |unused |unused |unused |
+        * |y|  |       |       |       |       |
+        * | |  |       |       |       |       |
+        * +++  16--|---------------|------------
+        *      +---V---------------V-----------+
+        *      |  dest_mix_gain_enable array   |
+        *      +-------------------------------+
+        */
+       /* example : MixerMatrix of LoLa280
+        * +-+  0-------8-2
+        * | |  |       | |
+        * |s|  | INPUT | |     INPUT
+        * |r|->|  ->   | |      ->
+        * |c|  |CAPTURE| | <-  OUTPUT
+        * | |  |  MIX  | |      MIX
+        * |g|  8----------
+        * |a|  |       | |
+        * |i|  | PLAYBK| |     PLAYBACK
+        * |n|->|  ->   | |      ->
+        * | |  |CAPTURE| | <-  OUTPUT
+        * |a|  |  MIX  | |      MIX
+        * |r|  8---|----|-
+        * |r|  +---V----V-------------------+
+        * |a|  | dest_mix_gain_enable array |
+        * |y|  +----------------------------+
         */
        if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
            chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
@@ -192,6 +213,9 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
                (((1U << chip->mixer.dest_phys_outs) - 1)
                 << chip->mixer.dest_phys_out_ofs);
 
+       snd_printdd("Mixer src_mask=%x, dest_mask=%x\n",
+                   chip->mixer.src_mask, chip->mixer.dest_mask);
+
        return 0;
 }
 
@@ -202,12 +226,19 @@ static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
 
        if (!(chip->mixer.src_mask & (1 << id)))
                return -EINVAL;
-       writew(gain, &chip->mixer.array->src_gain[id]);
        oldval = val = readl(&chip->mixer.array->src_gain_enable);
        if (on)
                val |= (1 << id);
        else
                val &= ~(1 << id);
+       /* test if values unchanged */
+       if ((val == oldval) &&
+           (gain == readw(&chip->mixer.array->src_gain[id])))
+               return 0;
+
+       snd_printdd("lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
+                       id, gain, val);
+       writew(gain, &chip->mixer.array->src_gain[id]);
        writel(val, &chip->mixer.array->src_gain_enable);
        lola_codec_flush(chip);
        /* inform micro-controller about the new source gain */
@@ -269,6 +300,7 @@ static int lola_mixer_set_mapping_gain(struct lola *chip,
                                src, dest);
 }
 
+#if 0 /* not used */
 static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
                                     unsigned int mask, unsigned short *gains)
 {
@@ -289,6 +321,7 @@ static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
        return lola_codec_write(chip, chip->mixer.nid,
                                LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
 }
+#endif /* not used */
 
 /*
  */
@@ -376,6 +409,8 @@ static int set_analog_volume(struct lola *chip, int dir,
                return 0;
        if (external_call)
                lola_codec_flush(chip);
+       snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n",
+                       dir, idx, val);
        err = lola_codec_write(chip, pin->nid,
                               LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
        if (err < 0)
@@ -427,23 +462,40 @@ static int init_mixer_values(struct lola *chip)
 {
        int i;
 
-       /* all src on */
+       /* all sample rate converters on */
        lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
 
-       /* clear all matrix */
+       /* clear all mixer matrix settings */
        memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
-       /* set src gain to 0dB */
+       /* inform firmware about all updated matrix columns - capture part */
+       for (i = 0; i < chip->mixer.dest_stream_ins; i++)
+               lola_codec_write(chip, chip->mixer.nid,
+                                LOLA_VERB_SET_DESTINATION_GAIN,
+                                i, 0);
+       /* inform firmware about all updated matrix columns - output part */
+       for (i = 0; i < chip->mixer.dest_phys_outs; i++)
+               lola_codec_write(chip, chip->mixer.nid,
+                                LOLA_VERB_SET_DESTINATION_GAIN,
+                                chip->mixer.dest_phys_out_ofs + i, 0);
+
+       /* set all digital input source (master) gains to 0dB */
        for (i = 0; i < chip->mixer.src_phys_ins; i++)
                lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
+
+       /* set all digital playback source (master) gains to 0dB */
        for (i = 0; i < chip->mixer.src_stream_outs; i++)
                lola_mixer_set_src_gain(chip,
                                        i + chip->mixer.src_stream_out_ofs,
                                        336, true); /* 0dB */
-       /* set 1:1 dest gain */
+       /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
        for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
                int src = i % chip->mixer.src_phys_ins;
                lola_mixer_set_mapping_gain(chip, src, i, 336, true);
        }
+       /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
+        * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
+        * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
+        */
        for (i = 0; i < chip->mixer.src_stream_outs; i++) {
                int src = chip->mixer.src_stream_out_ofs + i;
                int dst = chip->mixer.dest_phys_out_ofs +
@@ -693,6 +745,7 @@ static int __devinit create_src_gain_mixer(struct lola *chip,
                           snd_ctl_new1(&lola_src_gain_mixer, chip));
 }
 
+#if 0 /* not used */
 /*
  * destination gain (matrix-like) mixer
  */
@@ -781,6 +834,7 @@ static int __devinit create_dest_gain_mixer(struct lola *chip,
        return snd_ctl_add(chip->card,
                          snd_ctl_new1(&lola_dest_gain_mixer, chip));
 }
+#endif /* not used */
 
 /*
  */
@@ -798,14 +852,16 @@ int __devinit lola_create_mixer(struct lola *chip)
        if (err < 0)
                return err;
        err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
-                                   "Line Source Gain Volume");
+                                   "Digital Capture Volume");
        if (err < 0)
                return err;
        err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
                                    chip->mixer.src_stream_out_ofs,
-                                   "Stream Source Gain Volume");
+                                   "Digital Playback Volume");
        if (err < 0)
                return err;
+#if 0
+/* FIXME: buggy mixer matrix handling */
        err = create_dest_gain_mixer(chip,
                                     chip->mixer.src_phys_ins, 0,
                                     chip->mixer.dest_stream_ins, 0,
@@ -834,6 +890,6 @@ int __devinit lola_create_mixer(struct lola *chip)
                                     "Stream Playback Volume");
        if (err < 0)
                return err;
-
+#endif /* FIXME */
        return init_mixer_values(chip);
 }