At Tue, 16 Jul 2013 11:48:10 +0200,
David Henningsson wrote:
>
> This Conexant codec has a single jack that can be used as either
> headphone or mic (but not headset). The existing hp_mic functionality
> does not apply here, because the mic and the HP are on separate pins.
>
> Hence make a lighter version of what has been earlier done for Realtek
> codecs.
>
> BugLink: https://bugs.launchpad.net/bugs/1198030
> Tested-by: Franz Hsieh <email address hidden>
> Signed-off-by: David Henningsson <email address hidden>
At Tue, 16 Jul 2013 11:48:10 +0200, /bugs.launchpad .net/bugs/ 1198030
David Henningsson wrote:
>
> This Conexant codec has a single jack that can be used as either
> headphone or mic (but not headset). The existing hp_mic functionality
> does not apply here, because the mic and the HP are on separate pins.
>
> Hence make a lighter version of what has been earlier done for Realtek
> codecs.
>
> BugLink: https:/
> Tested-by: Franz Hsieh <email address hidden>
> Signed-off-by: David Henningsson <email address hidden>
Thanks, applied.
Takashi
> --- hda/patch_ conexant. c | 79 +++++++ +++++++ +++++++ +++++++ +++++++ ++++- pci/hda/ patch_conexant. c b/sound/ pci/hda/ patch_conexant. c pci/hda/ patch_conexant. c pci/hda/ patch_conexant. c parse_pin_ defcfg( ) */ CXT_STATIC_ QUIRKS gen_init( codec); >dynamic_ eapd) turn_eapd( codec, spec->num_eapds, spec->eapds, true); apply_fixup( codec, HDA_FIXUP_ ACT_INIT) ; LEMOTE_ A1205, STEREO_ DMIC, INC_MIC_ BOOST, HEADPHONE_ MIC_PIN, HEADPHONE_ MIC, stereo_ dmic(struct hda_codec *codec, increase_ mic_boost( struct hda_codec *codec, MUTE_SHIFT) ); headset_ mode(struct hda_codec *codec) imux_pins[ spec->gen. cur_mux[ 0]]; inputs[ i].is_headphone _mic; codec_write_ cache(codec, 0x1c, 0, 0x410, 0x7c); /* enable merged mode for analog int-mic */ hp_jack_ present = false; codec_write_ cache(codec, 0x1c, 0, 0x410, 0x54); /* disable merged mode for analog int-mic */ hp_jack_ present = snd_hda_ jack_detect( codec, spec->gen. autocfg. hp_pins[ 0]); gen_update_ outputs( codec); headset_ mode_hook( struct hda_codec *codec, headset_ mode(codec) ; headphone_ mic(struct hda_codec *codec, ACT_PRE_ PROBE: HEADPHONE_ MIC; ACT_PROBE: cap_sync_ hook = cxt_update_ headset_ mode_hook; automute_ hook = cxt_update_ headset_ mode; headset_ mode(codec) ; lenovo_ x200[] = { increase_ mic_boost, HEADPHONE_ MIC_PIN] = { HEADPHONE_ MIC, HEADPHONE_ MIC] = { headphone_ mic, QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_ STEREO_ DMIC), QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_ HEADPHONE_ MIC_PIN) , QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_ LENOVO_ TP410), QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_ LENOVO_ TP410), QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_ LENOVO_ TP410), auto(struct hda_codec *codec) apply_fixup( codec, HDA_FIXUP_ ACT_PRE_ PROBE); parse_pin_ defcfg( codec, &spec->gen.autocfg, NULL, 0); parse_pin_ defcfg( codec, &spec->gen.autocfg, NULL, auto(struct hda_codec *codec) bus->allow_ bus_reset = 1; apply_fixup( codec, HDA_FIXUP_ ACT_PROBE) ;
> sound/pci/
> 1 file changed, 78 insertions(+), 1 deletion(-)
>
> diff --git a/sound/
> index de00ce1..4edd2d0 100644
> --- a/sound/
> +++ b/sound/
> @@ -66,6 +66,8 @@ struct conexant_spec {
> hda_nid_t eapds[4];
> bool dynamic_eapd;
>
> + unsigned int parse_flags; /* flag for snd_hda_
> +
> #ifdef ENABLE_
> const struct snd_kcontrol_new *mixers[5];
> int num_mixers;
> @@ -3200,6 +3202,9 @@ static int cx_auto_init(struct hda_codec *codec)
> snd_hda_
> if (!spec-
> cx_auto_
> +
> + snd_hda_
> +
> return 0;
> }
>
> @@ -3224,6 +3229,8 @@ enum {
> CXT_PINCFG_
> CXT_FIXUP_
> CXT_FIXUP_
> + CXT_FIXUP_
> + CXT_FIXUP_
> };
>
> static void cxt_fixup_
> @@ -3246,6 +3253,59 @@ static void cxt5066_
> (0 << AC_AMPCAP_
> }
>
> +static void cxt_update_
> +{
> + /* The verbs used in this function were tested on a Conexant CX20751/2 codec. */
> + int i;
> + bool mic_mode = false;
> + struct conexant_spec *spec = codec->spec;
> + struct auto_pin_cfg *cfg = &spec->gen.autocfg;
> +
> + hda_nid_t mux_pin = spec->gen.
> +
> + for (i = 0; i < cfg->num_inputs; i++)
> + if (cfg->inputs[i].pin == mux_pin) {
> + mic_mode = !!cfg->
> + break;
> + }
> +
> + if (mic_mode) {
> + snd_hda_
> + spec->gen.
> + } else {
> + snd_hda_
> + spec->gen.
> + }
> +
> + snd_hda_
> +}
> +
> +static void cxt_update_
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + cxt_update_
> +}
> +
> +static void cxt_fixup_
> + const struct hda_fixup *fix, int action)
> +{
> + struct conexant_spec *spec = codec->spec;
> +
> + switch (action) {
> + case HDA_FIXUP_
> + spec->parse_flags |= HDA_PINCFG_
> + break;
> + case HDA_FIXUP_
> + spec->gen.
> + spec->gen.
> + break;
> + case HDA_FIXUP_ACT_INIT:
> + cxt_update_
> + break;
> + }
> +}
> +
> +
> /* ThinkPad X200 & co with cxt5051 */
> static const struct hda_pintbl cxt_pincfg_
> { 0x16, 0x042140ff }, /* HP (seq# overridden) */
> @@ -3302,6 +3362,19 @@ static const struct hda_fixup cxt_fixups[] = {
> .type = HDA_FIXUP_FUNC,
> .v.func = cxt5066_
> },
> + [CXT_FIXUP_
> + .type = HDA_FIXUP_PINS,
> + .chained = true,
> + .chain_id = CXT_FIXUP_
> + .v.pins = (const struct hda_pintbl[]) {
> + { 0x18, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
> + { }
> + }
> + },
> + [CXT_FIXUP_
> + .type = HDA_FIXUP_FUNC,
> + .v.func = cxt_fixup_
> + },
> };
>
> static const struct snd_pci_quirk cxt5051_fixups[] = {
> @@ -3311,6 +3384,7 @@ static const struct snd_pci_quirk cxt5051_fixups[] = {
>
> static const struct snd_pci_quirk cxt5066_fixups[] = {
> SND_PCI_
> + SND_PCI_
> SND_PCI_
> SND_PCI_
> SND_PCI_
> @@ -3395,7 +3469,8 @@ static int patch_conexant_
>
> snd_hda_
>
> - err = snd_hda_
> + err = snd_hda_
> + spec->parse_flags);
> if (err < 0)
> goto error;
>
> @@ -3416,6 +3491,8 @@ static int patch_conexant_
> codec->
> }
>
> + snd_hda_
> +
> return 0;
>
> error:
> --
> 1.7.9.5
>