From mboxrd@z Thu Jan 1 00:00:00 1970 From: Takashi Iwai Subject: Re: Intel HDA / ca0132: support for Alienware 15 Creative Sound Core3D-EX Date: Tue, 19 May 2015 06:59:18 +0200 Message-ID: References: <553AE4CF.3070805@gmx.com> <553E7B34.2080501@gmx.com> <553EB55D.4060701@gmx.com> <55400DF4.2080309@gmx.com> <5540FBFF.6020904@gmx.com> <55416BEE.5090003@gmx.com> <5546B501.7050207@gmx.com> <55510E3D.90508@gmx.com> <555A3A41.2010505@gmx.com> Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by alsa0.perex.cz (Postfix) with ESMTP id 51499261AD8 for ; Tue, 19 May 2015 06:59:19 +0200 (CEST) In-Reply-To: <555A3A41.2010505@gmx.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org To: Gabriele Martino Cc: alsa-devel@alsa-project.org List-Id: alsa-devel@alsa-project.org 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 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