aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2011-08-25 07:16:02 -0400
committerTakashi Iwai <tiwai@suse.de>2011-08-25 09:08:03 -0400
commit468c5458856236cde6df1b0654d32bf6625349a5 (patch)
tree3ba6b2218849311e6394bd71816ee3305b523fcd /sound
parent7675535958175b85b8117bcee245d9ecbc4d3d74 (diff)
ALSA: hda: Conexant: Allow different output types to share DAC
Headphones has stopped working for the original reported (a regression compared to 2.6.38). This is because Speaker and Headphones share the same DAC, in which case no Headphones volume control was created. This patch fixes so that both Speaker and Headphones volume controls are created in such scenario. BugLink: http://bugs.launchpad.net/bugs/817943 Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_conexant.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 5616444a8ed7..7696d05b9356 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3372,18 +3372,26 @@ static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
3372/* fill pin_dac_pair list from the pin and dac list */ 3372/* fill pin_dac_pair list from the pin and dac list */
3373static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins, 3373static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
3374 int num_pins, hda_nid_t *dacs, int *rest, 3374 int num_pins, hda_nid_t *dacs, int *rest,
3375 struct pin_dac_pair *filled, int type) 3375 struct pin_dac_pair *filled, int nums,
3376 int type)
3376{ 3377{
3377 int i, nums; 3378 int i, start = nums;
3378 3379
3379 nums = 0; 3380 for (i = 0; i < num_pins; i++, nums++) {
3380 for (i = 0; i < num_pins; i++) {
3381 filled[nums].pin = pins[i]; 3381 filled[nums].pin = pins[i];
3382 filled[nums].type = type; 3382 filled[nums].type = type;
3383 filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest); 3383 filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
3384 if (!filled[nums].dac && i > 0 && filled[0].dac) 3384 if (filled[nums].dac)
3385 continue;
3386 if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) {
3387 filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG;
3388 continue;
3389 }
3390 if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) {
3385 filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG; 3391 filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
3386 nums++; 3392 continue;
3393 }
3394 snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]);
3387 } 3395 }
3388 return nums; 3396 return nums;
3389} 3397}
@@ -3399,14 +3407,14 @@ static void cx_auto_parse_output(struct hda_codec *codec)
3399 rest = fill_cx_auto_dacs(codec, dacs); 3407 rest = fill_cx_auto_dacs(codec, dacs);
3400 /* parse all analog output pins */ 3408 /* parse all analog output pins */
3401 nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs, 3409 nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
3402 dacs, &rest, spec->dac_info, 3410 dacs, &rest, spec->dac_info, 0,
3403 AUTO_PIN_LINE_OUT); 3411 AUTO_PIN_LINE_OUT);
3404 nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs, 3412 nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
3405 dacs, &rest, spec->dac_info + nums, 3413 dacs, &rest, spec->dac_info, nums,
3406 AUTO_PIN_HP_OUT); 3414 AUTO_PIN_HP_OUT);
3407 nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs, 3415 nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
3408 dacs, &rest, spec->dac_info + nums, 3416 dacs, &rest, spec->dac_info, nums,
3409 AUTO_PIN_SPEAKER_OUT); 3417 AUTO_PIN_SPEAKER_OUT);
3410 spec->dac_info_filled = nums; 3418 spec->dac_info_filled = nums;
3411 /* fill multiout struct */ 3419 /* fill multiout struct */
3412 for (i = 0; i < nums; i++) { 3420 for (i = 0; i < nums; i++) {
@@ -4173,9 +4181,11 @@ static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
4173 hda_nid_t pin, const char *name, int idx) 4181 hda_nid_t pin, const char *name, int idx)
4174{ 4182{
4175 unsigned int caps; 4183 unsigned int caps;
4176 caps = query_amp_caps(codec, dac, HDA_OUTPUT); 4184 if (dac && !(dac & DAC_SLAVE_FLAG)) {
4177 if (caps & AC_AMPCAP_NUM_STEPS) 4185 caps = query_amp_caps(codec, dac, HDA_OUTPUT);
4178 return cx_auto_add_pb_volume(codec, dac, name, idx); 4186 if (caps & AC_AMPCAP_NUM_STEPS)
4187 return cx_auto_add_pb_volume(codec, dac, name, idx);
4188 }
4179 caps = query_amp_caps(codec, pin, HDA_OUTPUT); 4189 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
4180 if (caps & AC_AMPCAP_NUM_STEPS) 4190 if (caps & AC_AMPCAP_NUM_STEPS)
4181 return cx_auto_add_pb_volume(codec, pin, name, idx); 4191 return cx_auto_add_pb_volume(codec, pin, name, idx);
@@ -4198,8 +4208,6 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
4198 const char *label; 4208 const char *label;
4199 int idx, type; 4209 int idx, type;
4200 hda_nid_t dac = spec->dac_info[i].dac; 4210 hda_nid_t dac = spec->dac_info[i].dac;
4201 if (!dac || (dac & DAC_SLAVE_FLAG))
4202 continue;
4203 type = spec->dac_info[i].type; 4211 type = spec->dac_info[i].type;
4204 if (type == AUTO_PIN_LINE_OUT) 4212 if (type == AUTO_PIN_LINE_OUT)
4205 type = spec->autocfg.line_out_type; 4213 type = spec->autocfg.line_out_type;