Intel HDA / ca0132: support for Alienware 15 Creative Sound Core3D-EX
diff mbox

Message ID 5546B501.7050207@gmx.com
State New
Headers show

Commit Message

Gabriele Martino May 3, 2015, 11:53 p.m. UTC
On 30/04/2015 07:51, Takashi Iwai wrote:
> At Thu, 30 Apr 2015 01:40:30 +0200,
> Gabriele Martino wrote:
>> hdajacksensetest -c 1 -a
>> Pin 0x0b (Internal Speaker): present = Yes
>> Pin 0x0c (Not connected): present = No
>> Pin 0x0d (Not connected): present = No
>> Pin 0x0e (Not connected): present = No
>> Pin 0x0f (Not connected): present = Yes
>> Pin 0x10 (Not connected): present = No
>> Pin 0x11 (Black Line In, Left side): present = No
>> Pin 0x12 (Internal Mic, Mobile-In): present = No
>> Pin 0x13 (Not connected): present = No
>> Pin 0x18 (Not connected): present = No
>>
>> Pin 0x0f is still reported as not connected, but correctly detects the
>> jack if plugged.
>> If I turn off and on the "HP/Speaker Auto Detect" in alsamixer while
>> "HP/Speaker" is off, the correct output is detected.
>> If "HP/Speaker" is on, the behaviour is inconsistent.
>>
>> Is there a configuration file? Where can I find the metadata "Black Line
>> In, Left side"?
>> I don't know if it is related, but pavucontrol detects only the
>> "speakers" port.
>> On my previous laptop (with Creative Recon 3Di, another ca0132 card) I
>> could choose between "speakers and "headphones".
> It implies that the whole pin config BIOS provides is buggy.   The
> jack color, location, etc, all are parsed from 32bit pin configuration
> value for each pin.
>
> You need to correct the pin config and sets it statically in the
> driver.  hdajackretask can give you the map and reload it
> dynamically.
>
Finally got it.
I'm not sure about overriding the BIOS configuration: there is a new
version which fixes all the unconnected pins.
There is only a small issue: the internal speakers are now marked as
"Line out", which seems to mess up the "Ports" section in Pulseaudio.

Regards,
Gabriele
[codec]
0x11020011 0x10280685 0

[pincfg]
0x0b 0x90174010
0x0c 0x014580f0
0x0d 0x014570f0
0x0e 0x01c530f0
0x0f 0x0221401f
0x10 0x02216011
0x11 0x02012014
0x12 0x37a791f0
0x13 0x908700f0
0x18 0x500000f0

Comments

Takashi Iwai May 4, 2015, 12:30 p.m. UTC | #1
At Mon, 04 May 2015 01:53:37 +0200,
Gabriele Martino wrote:
> 
> On 30/04/2015 07:51, Takashi Iwai wrote:
> > At Thu, 30 Apr 2015 01:40:30 +0200,
> > Gabriele Martino wrote:
> >> hdajacksensetest -c 1 -a
> >> Pin 0x0b (Internal Speaker): present = Yes
> >> Pin 0x0c (Not connected): present = No
> >> Pin 0x0d (Not connected): present = No
> >> Pin 0x0e (Not connected): present = No
> >> Pin 0x0f (Not connected): present = Yes
> >> Pin 0x10 (Not connected): present = No
> >> Pin 0x11 (Black Line In, Left side): present = No
> >> Pin 0x12 (Internal Mic, Mobile-In): present = No
> >> Pin 0x13 (Not connected): present = No
> >> Pin 0x18 (Not connected): present = No
> >>
> >> Pin 0x0f is still reported as not connected, but correctly detects the
> >> jack if plugged.
> >> If I turn off and on the "HP/Speaker Auto Detect" in alsamixer while
> >> "HP/Speaker" is off, the correct output is detected.
> >> If "HP/Speaker" is on, the behaviour is inconsistent.
> >>
> >> Is there a configuration file? Where can I find the metadata "Black Line
> >> In, Left side"?
> >> I don't know if it is related, but pavucontrol detects only the
> >> "speakers" port.
> >> On my previous laptop (with Creative Recon 3Di, another ca0132 card) I
> >> could choose between "speakers and "headphones".
> > It implies that the whole pin config BIOS provides is buggy.   The
> > jack color, location, etc, all are parsed from 32bit pin configuration
> > value for each pin.
> >
> > You need to correct the pin config and sets it statically in the
> > driver.  hdajackretask can give you the map and reload it
> > dynamically.
> >
> Finally got it.
> I'm not sure about overriding the BIOS configuration: there is a new
> version which fixes all the unconnected pins.
> There is only a small issue: the internal speakers are now marked as
> "Line out", which seems to mess up the "Ports" section in Pulseaudio.

Hm, this can be changed via a proper pin config?

In anyway, I'm traveling in this week and next week, so cannot debug
the things.  Will check it later once when I back from vacation.  Just
ping me.


thanks,

Takashi
Gabriele Martino May 4, 2015, 11:28 p.m. UTC | #2
On 04/05/2015 14:30, Takashi Iwai wrote:
> At Mon, 04 May 2015 01:53:37 +0200,
> Gabriele Martino wrote:
>> Finally got it.
>> I'm not sure about overriding the BIOS configuration: there is a new
>> version which fixes all the unconnected pins.
>> There is only a small issue: the internal speakers are now marked as
>> "Line out", which seems to mess up the "Ports" section in Pulseaudio.
> Hm, this can be changed via a proper pin config?
Sure, that's why I attached hda-jack-retask.fw.
> In anyway, I'm traveling in this week and next week, so cannot debug
> the things.  Will check it later once when I back from vacation.  Just
> ping me.
Enjoy your vacation, I'll try to tidy up the code and make a decent
patch in the meanwhile.

Regards,
Gabriele

Patch
diff mbox

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4a4e7b2..04720ae 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -43,7 +43,7 @@ 
 #define FLOAT_TWO	0x40000000
 #define FLOAT_MINUS_5	0xc0a00000
 
-#define UNSOL_TAG_HP	0x10
+hda_nid_t UNSOL_TAG_HP = 0x10;
 #define UNSOL_TAG_AMIC1	0x12
 #define UNSOL_TAG_DSP	0x16
 
@@ -748,6 +748,7 @@  struct ca0132_spec {
 
 	struct hda_codec *codec;
 	struct delayed_work unsol_hp_work;
+	int quirk;
 
 #ifdef ENABLE_TUNING_CONTROLS
 	long cur_ctl_vals[TUNING_CTLS_COUNT];
@@ -755,6 +756,19 @@  struct ca0132_spec {
 };
 
 /*
+ * CA0132 quirks table
+ */
+enum {
+	QUIRK_NONE,
+	QUIRK_ALIENWARE,
+};
+
+static const struct snd_pci_quirk ca0132_quirks[] = {
+	SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15", QUIRK_ALIENWARE),
+	{}
+};
+
+/*
  * CA0132 codec access
  */
 static unsigned int codec_send_command(struct hda_codec *codec, hda_nid_t nid,
@@ -4479,8 +4493,19 @@  static struct hda_verb ca0132_init_verbs0[] = {
 	{}
 };
 
-static struct hda_verb ca0132_init_verbs1[] = {
-	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_HP},
+static struct hda_verb ca0132_init_verbs1_default[] = {
+	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x10}, /* UNSOL_TAG_HP is 0x10 */
+	{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_AMIC1},
+	/* config EAPD */
+	{0x0b, 0x78D, 0x00},
+	/*{0x0b, AC_VERB_SET_EAPD_BTLENABLE, 0x02},*/
+	/*{0x10, 0x78D, 0x02},*/
+	/*{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x02},*/
+	{}
+};
+
+static struct hda_verb ca0132_init_verbs1_alienware[] = {
+	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x0f}, /* UNSOL_TAG_HP is 0x0f */
 	{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_AMIC1},
 	/* config EAPD */
 	{0x0b, 0x78D, 0x00},
@@ -4617,7 +4642,13 @@  static void ca0132_config(struct hda_codec *codec)
 
 	spec->num_outputs = 2;
 	spec->out_pins[0] = 0x0b; /* speaker out */
-	spec->out_pins[1] = 0x10; /* headphone out */
+	if (spec->quirk == QUIRK_ALIENWARE) {
+		codec_dbg(codec, "ca0132_config: QUIRK_ALIENWARE applied.\n");
+		spec->out_pins[1] = 0x0f;
+	}
+	else{
+		spec->out_pins[1] = 0x10; /* headphone out */
+	}
 	spec->shared_out_nid = 0x2;
 
 	spec->num_inputs = 3;
@@ -4645,6 +4676,8 @@  static int patch_ca0132(struct hda_codec *codec)
 {
 	struct ca0132_spec *spec;
 	int err;
+	const struct snd_pci_quirk *quirk;
+	struct hda_verb *ca0132_init_verbs1;
 
 	codec_dbg(codec, "patch_ca0132\n");
 
@@ -4654,6 +4687,24 @@  static int patch_ca0132(struct hda_codec *codec)
 	codec->spec = spec;
 	spec->codec = codec;
 
+	quirk = snd_pci_quirk_lookup(codec->bus->pci, ca0132_quirks);
+	if (quirk) {
+		spec->quirk = quirk->value;
+	}
+	else{
+		spec->quirk = QUIRK_NONE;
+	}
+
+	/* Apply detected quirks */
+	if (spec->quirk == QUIRK_ALIENWARE) {
+		codec_dbg(codec, "patch_ca0132: QUIRK_ALIENWARE applied.\n");
+		UNSOL_TAG_HP = 0x0f;
+		ca0132_init_verbs1 = ca0132_init_verbs1_alienware;
+	}
+	else{
+		ca0132_init_verbs1 = ca0132_init_verbs1_default;
+	}
+
 	spec->dsp_state = DSP_DOWNLOAD_INIT;
 	spec->num_mixers = 1;
 	spec->mixers[0] = ca0132_mixer;