
At Mon, 18 May 2015 21:15:13 +0200, Gabriele Martino wrote:
This patch adds quirks detection to the Creative CA0132 codec, and the quirk for Alienware 15 (2015). Some quirks may need different pin configuration, so the relevant compile-time configuration has been removed. The pin configuration and related initialization verbs are generated at runtime instead, in ca0132_config() and ca0132_prepare_verbs().
Signed-off-by: Gabriele Martino g.martino@gmx.com
Applied, thanks.
Takashi
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 4a4e7b2..1c7a9ec 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -43,8 +43,6 @@ #define FLOAT_TWO 0x40000000 #define FLOAT_MINUS_5 0xc0a00000
-#define UNSOL_TAG_HP 0x10 -#define UNSOL_TAG_AMIC1 0x12 #define UNSOL_TAG_DSP 0x16
#define DSP_DMA_WRITE_BUFLEN_INIT (1UL<<18) @@ -703,8 +701,8 @@ unsigned int num_mixers; const struct hda_verb *base_init_verbs; const struct hda_verb *base_exit_verbs;
- const struct hda_verb *init_verbs[5];
- unsigned int num_init_verbs; /* exclude base init verbs */
const struct hda_verb *chip_init_verbs;
struct hda_verb *spec_init_verbs; struct auto_pin_cfg autocfg;
/* Nodes configurations */
@@ -719,6 +717,8 @@ unsigned int num_inputs; hda_nid_t shared_mic_nid; hda_nid_t shared_out_nid;
hda_nid_t unsol_tag_hp;
hda_nid_t unsol_tag_amic1;
/* chip access */ struct mutex chipio_mutex; /* chip access mutex */
@@ -748,10 +748,24 @@
struct hda_codec *codec; struct delayed_work unsol_hp_work;
- int quirk;
#ifdef ENABLE_TUNING_CONTROLS long cur_ctl_vals[TUNING_CTLS_COUNT]; #endif +};
+/*
- 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),
- {}
};
/* @@ -3227,7 +3241,7 @@ struct hda_jack_tbl *jack;
ca0132_select_out(spec->codec);
- jack = snd_hda_jack_tbl_get(spec->codec, UNSOL_TAG_HP);
- jack = snd_hda_jack_tbl_get(spec->codec, spec->unsol_tag_hp); if (jack) { jack->block_report = 0; snd_hda_jack_report_sync(spec->codec);
@@ -4417,8 +4431,9 @@
static void ca0132_init_unsol(struct hda_codec *codec) {
- snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_HP, hp_callback);
- snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_AMIC1,
- struct ca0132_spec *spec = codec->spec;
- snd_hda_jack_detect_enable_callback(codec, spec->unsol_tag_hp, hp_callback);
- snd_hda_jack_detect_enable_callback(codec, spec->unsol_tag_amic1, amic_callback); snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP, ca0132_process_dsp_response);
@@ -4476,17 +4491,6 @@ {0x15, 0x5E8, 0xC9}, {0x15, 0x717, 0x0D}, {0x15, 0x718, 0x20},
- {}
-};
-static struct hda_verb ca0132_init_verbs1[] = {
- {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_HP},
- {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},*/ {}
};
@@ -4569,8 +4573,8 @@
init_input(codec, cfg->dig_in_pin, spec->dig_in);
- for (i = 0; i < spec->num_init_verbs; i++)
snd_hda_sequence_write(codec, spec->init_verbs[i]);
snd_hda_sequence_write(codec, spec->chip_init_verbs);
snd_hda_sequence_write(codec, spec->spec_init_verbs);
ca0132_select_out(codec); ca0132_select_mic(codec);
@@ -4591,6 +4595,7 @@ snd_hda_sequence_write(codec, spec->base_exit_verbs); ca0132_exit_chip(codec); snd_hda_power_down(codec);
- kfree(spec->spec_init_verbs); kfree(codec->spec);
}
@@ -4617,18 +4622,26 @@
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->unsol_tag_hp = spec->out_pins[1];
- spec->num_inputs = 3; spec->adcs[0] = 0x7; /* digital mic / analog mic1 */ spec->adcs[1] = 0x8; /* analog mic2 */ spec->adcs[2] = 0xa; /* what u hear */
- spec->shared_mic_nid = 0x7;
spec->num_inputs = 3; spec->input_pins[0] = 0x12; spec->input_pins[1] = 0x11; spec->input_pins[2] = 0x13;
spec->shared_mic_nid = 0x7;
spec->unsol_tag_amic1 = spec->input_pins[0];
/* SPDIF I/O */ spec->dig_out = 0x05;
@@ -4641,10 +4654,56 @@ cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; }
+static int ca0132_prepare_verbs(struct hda_codec *codec) +{ +/* Verbs + terminator (an empty element) */ +#define NUM_SPEC_VERBS 4
- struct ca0132_spec *spec = codec->spec;
- spec->chip_init_verbs = ca0132_init_verbs0;
- spec->spec_init_verbs = kzalloc(sizeof(struct hda_verb) * NUM_SPEC_VERBS, GFP_KERNEL);
- if (!spec->spec_init_verbs)
return -ENOMEM;
- /* HP jack autodetection */
- spec->spec_init_verbs[0].nid = spec->unsol_tag_hp;
- spec->spec_init_verbs[0].param = AC_VERB_SET_UNSOLICITED_ENABLE;
- spec->spec_init_verbs[0].verb = AC_USRSP_EN | spec->unsol_tag_hp;
- /* MIC1 jack autodetection */
- spec->spec_init_verbs[1].nid = spec->unsol_tag_amic1;
- spec->spec_init_verbs[1].param = AC_VERB_SET_UNSOLICITED_ENABLE;
- spec->spec_init_verbs[1].verb = AC_USRSP_EN | spec->unsol_tag_amic1;
- /* config EAPD */
- spec->spec_init_verbs[2].nid = 0x0b;
- spec->spec_init_verbs[2].param = 0x78D;
- spec->spec_init_verbs[2].verb = 0x00;
- /* Previously commented configuration */
- /*
- spec->spec_init_verbs[3].nid = 0x0b;
- spec->spec_init_verbs[3].param = AC_VERB_SET_EAPD_BTLENABLE;
- spec->spec_init_verbs[3].verb = 0x02;
- spec->spec_init_verbs[4].nid = 0x10;
- spec->spec_init_verbs[4].param = 0x78D;
- spec->spec_init_verbs[4].verb = 0x02;
- spec->spec_init_verbs[5].nid = 0x10;
- spec->spec_init_verbs[5].param = AC_VERB_SET_EAPD_BTLENABLE;
- spec->spec_init_verbs[5].verb = 0x02;
- */
- /* Terminator: spec->spec_init_verbs[NUM_SPEC_VERBS-1] */
- return 0;
+}
static int patch_ca0132(struct hda_codec *codec) { struct ca0132_spec *spec; int err;
const struct snd_pci_quirk *quirk;
codec_dbg(codec, "patch_ca0132\n");
@@ -4654,15 +4713,19 @@ codec->spec = spec; spec->codec = codec;
/* Detect codec quirk */
quirk = snd_pci_quirk_lookup(codec->bus->pci, ca0132_quirks);
if (quirk)
spec->quirk = quirk->value;
else
spec->quirk = QUIRK_NONE;
spec->dsp_state = DSP_DOWNLOAD_INIT; spec->num_mixers = 1; spec->mixers[0] = ca0132_mixer;
spec->base_init_verbs = ca0132_base_init_verbs; spec->base_exit_verbs = ca0132_base_exit_verbs;
spec->init_verbs[0] = ca0132_init_verbs0;
spec->init_verbs[1] = ca0132_init_verbs1;
spec->num_init_verbs = 2;
INIT_DELAYED_WORK(&spec->unsol_hp_work, ca0132_unsol_hp_delayed);
@@ -4670,6 +4733,10 @@
ca0132_config(codec);
- err = ca0132_prepare_verbs(codec);
- if (err < 0)
return err;
- err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); if (err < 0) return err;
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel