aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorMarkus Bollinger <bollinger@digigram.com>2011-06-24 06:54:43 -0400
committerTakashi Iwai <tiwai@suse.de>2011-06-24 06:54:43 -0400
commit14705799138005dcb66fa9dfe3e9103e9ae7a897 (patch)
tree4a2898642ef5ed2d0b52d8be637e162238afac3e /sound/pci
parent3409fcd1f71d02025e3f179127a8ba243c525d78 (diff)
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: Markus Bollinger <bollinger@digigram.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/lola/lola.h2
-rw-r--r--sound/pci/lola/lola_mixer.c130
2 files changed, 94 insertions, 38 deletions
diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h
index d5708e29b16d..f0b100059efd 100644
--- a/sound/pci/lola/lola.h
+++ b/sound/pci/lola/lola.h
@@ -480,7 +480,7 @@ struct lola {
480 480
481/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */ 481/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
482#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f) 482#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f)
483#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res) ((res >> 7) & 0x1f) 483#define LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(res) ((res >> 7) & 0x1f)
484 484
485int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb, 485int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
486 unsigned int data, unsigned int extdata); 486 unsigned int data, unsigned int extdata);
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
index 5d518f1a712c..6b8d64812951 100644
--- a/sound/pci/lola/lola_mixer.c
+++ b/sound/pci/lola/lola_mixer.c
@@ -144,40 +144,61 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
144 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams; 144 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
145 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins; 145 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
146 146
147 /* mixer matrix can have unused areas between PhysIn and 147 /* mixer matrix may have unused areas between PhysIn and
148 * Play or Record and PhysOut zones 148 * Play or Record and PhysOut zones
149 */ 149 */
150 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins + 150 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
151 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val); 151 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
152 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins + 152 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
153 LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val); 153 LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
154 154
155 /* example : MixerMatrix of LoLa881 155 /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
156 * 0-------8------16-------8------16 156 * +-+ 0-------8------16-------8------16
157 * | | | | | 157 * | | | | | | |
158 * | INPUT | | INPUT | | 158 * |s| | INPUT | | INPUT | |
159 * | -> |unused | -> |unused | 159 * | |->| -> |unused | -> |unused |
160 * | RECORD| | OUTPUT| | 160 * |r| |CAPTURE| | OUTPUT| |
161 * | | | | | 161 * | | | MIX | | MIX | |
162 * 8-------------------------------- 162 * |c| 8--------------------------------
163 * | | | | | 163 * | | | | | | |
164 * | | | | | 164 * | | | | | | |
165 * |unused |unused |unused |unused | 165 * |g| |unused |unused |unused |unused |
166 * | | | | | 166 * | | | | | | |
167 * | | | | | 167 * |a| | | | | |
168 * 16------------------------------- 168 * | | 16-------------------------------
169 * | | | | | 169 * |i| | | | | |
170 * | PLAY | | PLAY | | 170 * | | | PLAYBK| | PLAYBK| |
171 * | -> |unused | -> |unused | 171 * |n|->| -> |unused | -> |unused |
172 * | RECORD| | OUTPUT| | 172 * | | |CAPTURE| | OUTPUT| |
173 * | | | | | 173 * | | | MIX | | MIX | |
174 * 8-------------------------------- 174 * |a| 8--------------------------------
175 * | | | | | 175 * |r| | | | | |
176 * | | | | | 176 * |r| | | | | |
177 * |unused |unused |unused |unused | 177 * |a| |unused |unused |unused |unused |
178 * | | | | | 178 * |y| | | | | |
179 * | | | | | 179 * | | | | | | |
180 * 16------------------------------- 180 * +++ 16--|---------------|------------
181 * +---V---------------V-----------+
182 * | dest_mix_gain_enable array |
183 * +-------------------------------+
184 */
185 /* example : MixerMatrix of LoLa280
186 * +-+ 0-------8-2
187 * | | | | |
188 * |s| | INPUT | | INPUT
189 * |r|->| -> | | ->
190 * |c| |CAPTURE| | <- OUTPUT
191 * | | | MIX | | MIX
192 * |g| 8----------
193 * |a| | | |
194 * |i| | PLAYBK| | PLAYBACK
195 * |n|->| -> | | ->
196 * | | |CAPTURE| | <- OUTPUT
197 * |a| | MIX | | MIX
198 * |r| 8---|----|-
199 * |r| +---V----V-------------------+
200 * |a| | dest_mix_gain_enable array |
201 * |y| +----------------------------+
181 */ 202 */
182 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT || 203 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
183 chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) { 204 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 (((1U << chip->mixer.dest_phys_outs) - 1) 213 (((1U << chip->mixer.dest_phys_outs) - 1)
193 << chip->mixer.dest_phys_out_ofs); 214 << chip->mixer.dest_phys_out_ofs);
194 215
216 snd_printdd("Mixer src_mask=%x, dest_mask=%x\n",
217 chip->mixer.src_mask, chip->mixer.dest_mask);
218
195 return 0; 219 return 0;
196} 220}
197 221
@@ -202,12 +226,19 @@ static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
202 226
203 if (!(chip->mixer.src_mask & (1 << id))) 227 if (!(chip->mixer.src_mask & (1 << id)))
204 return -EINVAL; 228 return -EINVAL;
205 writew(gain, &chip->mixer.array->src_gain[id]);
206 oldval = val = readl(&chip->mixer.array->src_gain_enable); 229 oldval = val = readl(&chip->mixer.array->src_gain_enable);
207 if (on) 230 if (on)
208 val |= (1 << id); 231 val |= (1 << id);
209 else 232 else
210 val &= ~(1 << id); 233 val &= ~(1 << id);
234 /* test if values unchanged */
235 if ((val == oldval) &&
236 (gain == readw(&chip->mixer.array->src_gain[id])))
237 return 0;
238
239 snd_printdd("lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
240 id, gain, val);
241 writew(gain, &chip->mixer.array->src_gain[id]);
211 writel(val, &chip->mixer.array->src_gain_enable); 242 writel(val, &chip->mixer.array->src_gain_enable);
212 lola_codec_flush(chip); 243 lola_codec_flush(chip);
213 /* inform micro-controller about the new source gain */ 244 /* inform micro-controller about the new source gain */
@@ -269,6 +300,7 @@ static int lola_mixer_set_mapping_gain(struct lola *chip,
269 src, dest); 300 src, dest);
270} 301}
271 302
303#if 0 /* not used */
272static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id, 304static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
273 unsigned int mask, unsigned short *gains) 305 unsigned int mask, unsigned short *gains)
274{ 306{
@@ -289,6 +321,7 @@ static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
289 return lola_codec_write(chip, chip->mixer.nid, 321 return lola_codec_write(chip, chip->mixer.nid,
290 LOLA_VERB_SET_DESTINATION_GAIN, id, 0); 322 LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
291} 323}
324#endif /* not used */
292 325
293/* 326/*
294 */ 327 */
@@ -376,6 +409,8 @@ static int set_analog_volume(struct lola *chip, int dir,
376 return 0; 409 return 0;
377 if (external_call) 410 if (external_call)
378 lola_codec_flush(chip); 411 lola_codec_flush(chip);
412 snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n",
413 dir, idx, val);
379 err = lola_codec_write(chip, pin->nid, 414 err = lola_codec_write(chip, pin->nid,
380 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0); 415 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
381 if (err < 0) 416 if (err < 0)
@@ -427,23 +462,40 @@ static int init_mixer_values(struct lola *chip)
427{ 462{
428 int i; 463 int i;
429 464
430 /* all src on */ 465 /* all sample rate converters on */
431 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false); 466 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
432 467
433 /* clear all matrix */ 468 /* clear all mixer matrix settings */
434 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array)); 469 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
435 /* set src gain to 0dB */ 470 /* inform firmware about all updated matrix columns - capture part */
471 for (i = 0; i < chip->mixer.dest_stream_ins; i++)
472 lola_codec_write(chip, chip->mixer.nid,
473 LOLA_VERB_SET_DESTINATION_GAIN,
474 i, 0);
475 /* inform firmware about all updated matrix columns - output part */
476 for (i = 0; i < chip->mixer.dest_phys_outs; i++)
477 lola_codec_write(chip, chip->mixer.nid,
478 LOLA_VERB_SET_DESTINATION_GAIN,
479 chip->mixer.dest_phys_out_ofs + i, 0);
480
481 /* set all digital input source (master) gains to 0dB */
436 for (i = 0; i < chip->mixer.src_phys_ins; i++) 482 for (i = 0; i < chip->mixer.src_phys_ins; i++)
437 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */ 483 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
484
485 /* set all digital playback source (master) gains to 0dB */
438 for (i = 0; i < chip->mixer.src_stream_outs; i++) 486 for (i = 0; i < chip->mixer.src_stream_outs; i++)
439 lola_mixer_set_src_gain(chip, 487 lola_mixer_set_src_gain(chip,
440 i + chip->mixer.src_stream_out_ofs, 488 i + chip->mixer.src_stream_out_ofs,
441 336, true); /* 0dB */ 489 336, true); /* 0dB */
442 /* set 1:1 dest gain */ 490 /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
443 for (i = 0; i < chip->mixer.dest_stream_ins; i++) { 491 for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
444 int src = i % chip->mixer.src_phys_ins; 492 int src = i % chip->mixer.src_phys_ins;
445 lola_mixer_set_mapping_gain(chip, src, i, 336, true); 493 lola_mixer_set_mapping_gain(chip, src, i, 336, true);
446 } 494 }
495 /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
496 * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
497 * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
498 */
447 for (i = 0; i < chip->mixer.src_stream_outs; i++) { 499 for (i = 0; i < chip->mixer.src_stream_outs; i++) {
448 int src = chip->mixer.src_stream_out_ofs + i; 500 int src = chip->mixer.src_stream_out_ofs + i;
449 int dst = chip->mixer.dest_phys_out_ofs + 501 int dst = chip->mixer.dest_phys_out_ofs +
@@ -693,6 +745,7 @@ static int __devinit create_src_gain_mixer(struct lola *chip,
693 snd_ctl_new1(&lola_src_gain_mixer, chip)); 745 snd_ctl_new1(&lola_src_gain_mixer, chip));
694} 746}
695 747
748#if 0 /* not used */
696/* 749/*
697 * destination gain (matrix-like) mixer 750 * destination gain (matrix-like) mixer
698 */ 751 */
@@ -781,6 +834,7 @@ static int __devinit create_dest_gain_mixer(struct lola *chip,
781 return snd_ctl_add(chip->card, 834 return snd_ctl_add(chip->card,
782 snd_ctl_new1(&lola_dest_gain_mixer, chip)); 835 snd_ctl_new1(&lola_dest_gain_mixer, chip));
783} 836}
837#endif /* not used */
784 838
785/* 839/*
786 */ 840 */
@@ -798,14 +852,16 @@ int __devinit lola_create_mixer(struct lola *chip)
798 if (err < 0) 852 if (err < 0)
799 return err; 853 return err;
800 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0, 854 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
801 "Line Source Gain Volume"); 855 "Digital Capture Volume");
802 if (err < 0) 856 if (err < 0)
803 return err; 857 return err;
804 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs, 858 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
805 chip->mixer.src_stream_out_ofs, 859 chip->mixer.src_stream_out_ofs,
806 "Stream Source Gain Volume"); 860 "Digital Playback Volume");
807 if (err < 0) 861 if (err < 0)
808 return err; 862 return err;
863#if 0
864/* FIXME: buggy mixer matrix handling */
809 err = create_dest_gain_mixer(chip, 865 err = create_dest_gain_mixer(chip,
810 chip->mixer.src_phys_ins, 0, 866 chip->mixer.src_phys_ins, 0,
811 chip->mixer.dest_stream_ins, 0, 867 chip->mixer.dest_stream_ins, 0,
@@ -834,6 +890,6 @@ int __devinit lola_create_mixer(struct lola *chip)
834 "Stream Playback Volume"); 890 "Stream Playback Volume");
835 if (err < 0) 891 if (err < 0)
836 return err; 892 return err;
837 893#endif /* FIXME */
838 return init_mixer_values(chip); 894 return init_mixer_values(chip);
839} 895}