Patchwork [oneiric] fix sound output on acer aspire 3830TG

login
register
mail settings
Submitter David Henningsson
Date Aug. 1, 2011, 7:06 a.m.
Message ID <4E36507D.1080600@canonical.com>
Download mbox | patch
Permalink /patch/107684/
State New
Headers show

Comments

David Henningsson - Aug. 1, 2011, 7:06 a.m.
The attached, cherrypicked patch is necessary for sound output to work 
on Acer Aspire 3830 TG. Please apply to Oneiric as this patch is 
originally scheduled for 3.1 upstream.

http://bugs.launchpad.net/bugs/783582
Tim Gardner - Aug. 1, 2011, 1:19 p.m.
On 08/01/2011 01:06 AM, David Henningsson wrote:
> The attached, cherrypicked patch is necessary for sound output to work
> on Acer Aspire 3830 TG. Please apply to Oneiric as this patch is
> originally scheduled for 3.1 upstream.
>
> http://bugs.launchpad.net/bugs/783582
>
Andy Whitcroft - Aug. 1, 2011, 5:53 p.m.
On Mon, Aug 01, 2011 at 09:06:37AM +0200, David Henningsson wrote:
> The attached, cherrypicked patch is necessary for sound output to
> work on Acer Aspire 3830 TG. Please apply to Oneiric as this patch
> is originally scheduled for 3.1 upstream.
> 
> http://bugs.launchpad.net/bugs/783582
> 
> -- 
> David Henningsson, Canonical Ltd.
> http://launchpad.net/~diwic

> From cad167954afec0f961e1122907219c57e5e8e6d9 Mon Sep 17 00:00:00 2001
> From: Takashi Iwai <tiwai@suse.de>
> Date: Mon, 11 Jul 2011 14:46:44 +0200
> Subject: [PATCH] ALSA: hda - Turn on extra EAPDs on Conexant codecs
> 
> Some machines seem to use EAPD control of the unused pin for controlling
> the overall EAPD.  Since the driver currently doesn't check the EAPD of
> unused pins, the EAPD isn't enabled.  For avoiding such a problem, turn
> all extra EAPDs on as default.
> 
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> (cherry picked from commit 19110595c89b2d606883b7cb99260c7e47fd2143)
> 
> BugLink: http://bugs.launchpad.net/bugs/783582
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
> ---
>  sound/pci/hda/patch_conexant.c |   39 +++++++++++++++++++++++++++++++++++++++
>  1 files changed, 39 insertions(+), 0 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
> index 1ab6663..f32682b 100644
> --- a/sound/pci/hda/patch_conexant.c
> +++ b/sound/pci/hda/patch_conexant.c
> @@ -155,6 +155,10 @@ struct conexant_spec {
>  	unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
>  
>  	unsigned int beep_amp;
> +
> +	/* extra EAPD pins */
> +	unsigned int num_eapds;
> +	hda_nid_t eapds[4];
>  };
>  
>  static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
> @@ -3911,6 +3915,38 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
>  #define cx_auto_parse_beep(codec)
>  #endif
>  
> +static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
> +{
> +	int i;
> +	for (i = 0; i < nums; i++)
> +		if (list[i] == nid)
> +			return true;
> +	return false;
> +}
> +
> +/* parse extra-EAPD that aren't assigned to any pins */
> +static void cx_auto_parse_eapd(struct hda_codec *codec)
> +{
> +	struct conexant_spec *spec = codec->spec;
> +	struct auto_pin_cfg *cfg = &spec->autocfg;
> +	hda_nid_t nid, end_nid;
> +
> +	end_nid = codec->start_nid + codec->num_nodes;
> +	for (nid = codec->start_nid; nid < end_nid; nid++) {
> +		if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
> +			continue;
> +		if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
> +			continue;
> +		if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
> +		    found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
> +		    found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
> +			continue;
> +		spec->eapds[spec->num_eapds++] = nid;
> +		if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
> +			break;
> +	}
> +}
> +
>  static int cx_auto_parse_auto_config(struct hda_codec *codec)
>  {
>  	struct conexant_spec *spec = codec->spec;
> @@ -3924,6 +3960,7 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec)
>  	cx_auto_parse_input(codec);
>  	cx_auto_parse_digital(codec);
>  	cx_auto_parse_beep(codec);
> +	cx_auto_parse_eapd(codec);
>  	return 0;
>  }
>  
> @@ -4011,6 +4048,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
>  		}
>  	}
>  	cx_auto_update_speakers(codec);
> +	/* turn on/off extra EAPDs, too */
> +	cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
>  }
>  
>  static void cx_auto_init_input(struct hda_codec *codec)

Gah Vile.  I'd probabally have liked to see a diagnostic when the eapd
array is full.  But if its what upstream are doing in 3.1, then i guess:

Acked-by: Andy Whitcroft <apw@canonical.com>

-apw

Patch

From cad167954afec0f961e1122907219c57e5e8e6d9 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Mon, 11 Jul 2011 14:46:44 +0200
Subject: [PATCH] ALSA: hda - Turn on extra EAPDs on Conexant codecs

Some machines seem to use EAPD control of the unused pin for controlling
the overall EAPD.  Since the driver currently doesn't check the EAPD of
unused pins, the EAPD isn't enabled.  For avoiding such a problem, turn
all extra EAPDs on as default.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
(cherry picked from commit 19110595c89b2d606883b7cb99260c7e47fd2143)

BugLink: http://bugs.launchpad.net/bugs/783582
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 sound/pci/hda/patch_conexant.c |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 1ab6663..f32682b 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -155,6 +155,10 @@  struct conexant_spec {
 	unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
 
 	unsigned int beep_amp;
+
+	/* extra EAPD pins */
+	unsigned int num_eapds;
+	hda_nid_t eapds[4];
 };
 
 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -3911,6 +3915,38 @@  static void cx_auto_parse_beep(struct hda_codec *codec)
 #define cx_auto_parse_beep(codec)
 #endif
 
+static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
+{
+	int i;
+	for (i = 0; i < nums; i++)
+		if (list[i] == nid)
+			return true;
+	return false;
+}
+
+/* parse extra-EAPD that aren't assigned to any pins */
+static void cx_auto_parse_eapd(struct hda_codec *codec)
+{
+	struct conexant_spec *spec = codec->spec;
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+	hda_nid_t nid, end_nid;
+
+	end_nid = codec->start_nid + codec->num_nodes;
+	for (nid = codec->start_nid; nid < end_nid; nid++) {
+		if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
+			continue;
+		if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
+			continue;
+		if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
+		    found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
+		    found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
+			continue;
+		spec->eapds[spec->num_eapds++] = nid;
+		if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
+			break;
+	}
+}
+
 static int cx_auto_parse_auto_config(struct hda_codec *codec)
 {
 	struct conexant_spec *spec = codec->spec;
@@ -3924,6 +3960,7 @@  static int cx_auto_parse_auto_config(struct hda_codec *codec)
 	cx_auto_parse_input(codec);
 	cx_auto_parse_digital(codec);
 	cx_auto_parse_beep(codec);
+	cx_auto_parse_eapd(codec);
 	return 0;
 }
 
@@ -4011,6 +4048,8 @@  static void cx_auto_init_output(struct hda_codec *codec)
 		}
 	}
 	cx_auto_update_speakers(codec);
+	/* turn on/off extra EAPDs, too */
+	cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
 }
 
 static void cx_auto_init_input(struct hda_codec *codec)
-- 
1.7.4.1