Commit 14705799 authored by Markus Bollinger's avatar Markus Bollinger Committed by Takashi Iwai

ALSA: lola - Fix for Lola280 board

- 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: default avatarMarkus Bollinger <bollinger@digigram.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 3409fcd1
...@@ -480,7 +480,7 @@ struct lola { ...@@ -480,7 +480,7 @@ struct lola {
/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */ /* 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_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, int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
unsigned int data, unsigned int extdata); unsigned int data, unsigned int extdata);
......
...@@ -144,40 +144,61 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid) ...@@ -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_stream_ins = chip->pcm[CAPT].num_streams;
chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins; 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 * Play or Record and PhysOut zones
*/ */
chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins + chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val); LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins + chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val); LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
/* example : MixerMatrix of LoLa881 /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
* 0-------8------16-------8------16 * +-+ 0-------8------16-------8------16
* | | | | | * | | | | | | |
* | INPUT | | INPUT | | * |s| | INPUT | | INPUT | |
* | -> |unused | -> |unused | * | |->| -> |unused | -> |unused |
* | RECORD| | OUTPUT| | * |r| |CAPTURE| | OUTPUT| |
* | | | | | * | | | MIX | | MIX | |
* 8-------------------------------- * |c| 8--------------------------------
* | | | | | * | | | | | | |
* | | | | | * | | | | | | |
* |unused |unused |unused |unused | * |g| |unused |unused |unused |unused |
* | | | | | * | | | | | | |
* | | | | | * |a| | | | | |
* 16------------------------------- * | | 16-------------------------------
* | | | | | * |i| | | | | |
* | PLAY | | PLAY | | * | | | PLAYBK| | PLAYBK| |
* | -> |unused | -> |unused | * |n|->| -> |unused | -> |unused |
* | RECORD| | OUTPUT| | * | | |CAPTURE| | OUTPUT| |
* | | | | | * | | | MIX | | MIX | |
* 8-------------------------------- * |a| 8--------------------------------
* | | | | | * |r| | | | | |
* | | | | | * |r| | | | | |
* |unused |unused |unused |unused | * |a| |unused |unused |unused |unused |
* | | | | | * |y| | | | | |
* | | | | | * | | | | | | |
* 16------------------------------- * +++ 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 || if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_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) ...@@ -192,6 +213,9 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
(((1U << chip->mixer.dest_phys_outs) - 1) (((1U << chip->mixer.dest_phys_outs) - 1)
<< chip->mixer.dest_phys_out_ofs); << 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; return 0;
} }
...@@ -202,12 +226,19 @@ static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id, ...@@ -202,12 +226,19 @@ static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
if (!(chip->mixer.src_mask & (1 << id))) if (!(chip->mixer.src_mask & (1 << id)))
return -EINVAL; return -EINVAL;
writew(gain, &chip->mixer.array->src_gain[id]);
oldval = val = readl(&chip->mixer.array->src_gain_enable); oldval = val = readl(&chip->mixer.array->src_gain_enable);
if (on) if (on)
val |= (1 << id); val |= (1 << id);
else else
val &= ~(1 << id); 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); writel(val, &chip->mixer.array->src_gain_enable);
lola_codec_flush(chip); lola_codec_flush(chip);
/* inform micro-controller about the new source gain */ /* inform micro-controller about the new source gain */
...@@ -269,6 +300,7 @@ static int lola_mixer_set_mapping_gain(struct lola *chip, ...@@ -269,6 +300,7 @@ static int lola_mixer_set_mapping_gain(struct lola *chip,
src, dest); src, dest);
} }
#if 0 /* not used */
static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id, static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
unsigned int mask, unsigned short *gains) unsigned int mask, unsigned short *gains)
{ {
...@@ -289,6 +321,7 @@ static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id, ...@@ -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, return lola_codec_write(chip, chip->mixer.nid,
LOLA_VERB_SET_DESTINATION_GAIN, id, 0); LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
} }
#endif /* not used */
/* /*
*/ */
...@@ -376,6 +409,8 @@ static int set_analog_volume(struct lola *chip, int dir, ...@@ -376,6 +409,8 @@ static int set_analog_volume(struct lola *chip, int dir,
return 0; return 0;
if (external_call) if (external_call)
lola_codec_flush(chip); 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, err = lola_codec_write(chip, pin->nid,
LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0); LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
if (err < 0) if (err < 0)
...@@ -427,23 +462,40 @@ static int init_mixer_values(struct lola *chip) ...@@ -427,23 +462,40 @@ static int init_mixer_values(struct lola *chip)
{ {
int i; int i;
/* all src on */ /* all sample rate converters on */
lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false); 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)); 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++) for (i = 0; i < chip->mixer.src_phys_ins; i++)
lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */ 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++) for (i = 0; i < chip->mixer.src_stream_outs; i++)
lola_mixer_set_src_gain(chip, lola_mixer_set_src_gain(chip,
i + chip->mixer.src_stream_out_ofs, i + chip->mixer.src_stream_out_ofs,
336, true); /* 0dB */ 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++) { for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
int src = i % chip->mixer.src_phys_ins; int src = i % chip->mixer.src_phys_ins;
lola_mixer_set_mapping_gain(chip, src, i, 336, true); 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++) { for (i = 0; i < chip->mixer.src_stream_outs; i++) {
int src = chip->mixer.src_stream_out_ofs + i; int src = chip->mixer.src_stream_out_ofs + i;
int dst = chip->mixer.dest_phys_out_ofs + int dst = chip->mixer.dest_phys_out_ofs +
...@@ -693,6 +745,7 @@ static int __devinit create_src_gain_mixer(struct lola *chip, ...@@ -693,6 +745,7 @@ static int __devinit create_src_gain_mixer(struct lola *chip,
snd_ctl_new1(&lola_src_gain_mixer, chip)); snd_ctl_new1(&lola_src_gain_mixer, chip));
} }
#if 0 /* not used */
/* /*
* destination gain (matrix-like) mixer * destination gain (matrix-like) mixer
*/ */
...@@ -781,6 +834,7 @@ static int __devinit create_dest_gain_mixer(struct lola *chip, ...@@ -781,6 +834,7 @@ static int __devinit create_dest_gain_mixer(struct lola *chip,
return snd_ctl_add(chip->card, return snd_ctl_add(chip->card,
snd_ctl_new1(&lola_dest_gain_mixer, chip)); snd_ctl_new1(&lola_dest_gain_mixer, chip));
} }
#endif /* not used */
/* /*
*/ */
...@@ -798,14 +852,16 @@ int __devinit lola_create_mixer(struct lola *chip) ...@@ -798,14 +852,16 @@ int __devinit lola_create_mixer(struct lola *chip)
if (err < 0) if (err < 0)
return err; return err;
err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0, err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
"Line Source Gain Volume"); "Digital Capture Volume");
if (err < 0) if (err < 0)
return err; return err;
err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs, err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
chip->mixer.src_stream_out_ofs, chip->mixer.src_stream_out_ofs,
"Stream Source Gain Volume"); "Digital Playback Volume");
if (err < 0) if (err < 0)
return err; return err;
#if 0
/* FIXME: buggy mixer matrix handling */
err = create_dest_gain_mixer(chip, err = create_dest_gain_mixer(chip,
chip->mixer.src_phys_ins, 0, chip->mixer.src_phys_ins, 0,
chip->mixer.dest_stream_ins, 0, chip->mixer.dest_stream_ins, 0,
...@@ -834,6 +890,6 @@ int __devinit lola_create_mixer(struct lola *chip) ...@@ -834,6 +890,6 @@ int __devinit lola_create_mixer(struct lola *chip)
"Stream Playback Volume"); "Stream Playback Volume");
if (err < 0) if (err < 0)
return err; return err;
#endif /* FIXME */
return init_mixer_values(chip); return init_mixer_values(chip);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment