diff options
author | Markus Bollinger <bollinger@digigram.com> | 2011-06-24 06:54:43 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-06-24 06:54:43 -0400 |
commit | 14705799138005dcb66fa9dfe3e9103e9ae7a897 (patch) | |
tree | 4a2898642ef5ed2d0b52d8be637e162238afac3e /sound/pci | |
parent | 3409fcd1f71d02025e3f179127a8ba243c525d78 (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.h | 2 | ||||
-rw-r--r-- | sound/pci/lola/lola_mixer.c | 130 |
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 | ||
485 | int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb, | 485 | int 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 */ | ||
272 | static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id, | 304 | static 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 | } |