Loading sound/pci/hda/patch_conexant.c +111 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include <linux/slab.h> #include <linux/pci.h> #include <sound/core.h> #include <sound/jack.h> #include "hda_codec.h" #include "hda_local.h" Loading @@ -37,7 +39,20 @@ #define CONEXANT_HP_EVENT 0x37 #define CONEXANT_MIC_EVENT 0x38 /* Conexant 5051 specific */ #define CXT5051_SPDIF_OUT 0x1C #define CXT5051_PORTB_EVENT 0x38 #define CXT5051_PORTC_EVENT 0x39 struct conexant_jack { hda_nid_t nid; int type; struct snd_jack *jack; }; struct conexant_spec { Loading Loading @@ -83,6 +98,9 @@ struct conexant_spec { unsigned int spdif_route; /* jack detection */ struct snd_array jacks; /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; struct hda_input_mux private_imux; Loading Loading @@ -329,6 +347,86 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_mux[adc_idx]); } static int conexant_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { struct conexant_spec *spec; struct conexant_jack *jack; const char *name; spec = codec->spec; snd_array_init(&spec->jacks, sizeof(*jack), 32); jack = snd_array_new(&spec->jacks); name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; if (!jack) return -ENOMEM; jack->nid = nid; jack->type = type; return snd_jack_new(codec->bus->card, name, type, &jack->jack); } static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) { struct conexant_spec *spec = codec->spec; struct conexant_jack *jacks = spec->jacks.list; if (jacks) { int i; for (i = 0; i < spec->jacks.used; i++) { if (jacks->nid == nid) { unsigned int present; present = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; present = (present) ? jacks->type : 0 ; snd_jack_report(jacks->jack, present); } jacks++; } } } static int conexant_init_jacks(struct hda_codec *codec) { #ifdef CONFIG_SND_JACK struct conexant_spec *spec = codec->spec; int i; for (i = 0; i < spec->num_init_verbs; i++) { const struct hda_verb *hv; hv = spec->init_verbs[i]; while (hv->nid) { int err = 0; switch (hv->param ^ AC_USRSP_EN) { case CONEXANT_HP_EVENT: err = conexant_add_jack(codec, hv->nid, SND_JACK_HEADPHONE); conexant_report_jack(codec, hv->nid); break; case CXT5051_PORTC_EVENT: case CONEXANT_MIC_EVENT: err = conexant_add_jack(codec, hv->nid, SND_JACK_MICROPHONE); conexant_report_jack(codec, hv->nid); break; } if (err < 0) return err; ++hv; } } #endif return 0; } static int conexant_init(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; Loading @@ -341,6 +439,16 @@ static int conexant_init(struct hda_codec *codec) static void conexant_free(struct hda_codec *codec) { #ifdef CONFIG_SND_JACK struct conexant_spec *spec = codec->spec; if (spec->jacks.list) { struct conexant_jack *jacks = spec->jacks.list; int i; for (i = 0; i < spec->jacks.used; i++) snd_device_free(codec->bus->card, &jacks[i].jack); snd_array_free(&spec->jacks); } #endif kfree(codec->spec); } Loading Loading @@ -1526,9 +1634,6 @@ static int patch_cxt5047(struct hda_codec *codec) /* Conexant 5051 specific */ static hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; #define CXT5051_SPDIF_OUT 0x1C #define CXT5051_PORTB_EVENT 0x38 #define CXT5051_PORTC_EVENT 0x39 static struct hda_channel_mode cxt5051_modes[1] = { { 2, NULL }, Loading Loading @@ -1608,6 +1713,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec) static void cxt5051_hp_unsol_event(struct hda_codec *codec, unsigned int res) { int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; switch (res >> 26) { case CONEXANT_HP_EVENT: cxt5051_hp_automute(codec); Loading @@ -1619,6 +1725,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, cxt5051_portc_automic(codec); break; } conexant_report_jack(codec, nid); } static struct snd_kcontrol_new cxt5051_mixers[] = { Loading Loading @@ -1693,6 +1800,7 @@ static struct hda_verb cxt5051_init_verbs[] = { static int cxt5051_init(struct hda_codec *codec) { conexant_init(codec); conexant_init_jacks(codec); if (codec->patch_ops.unsol_event) { cxt5051_hp_automute(codec); cxt5051_portb_automic(codec); Loading sound/pci/hda/patch_realtek.c +2 −1 Original line number Diff line number Diff line Loading @@ -8467,6 +8467,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), Loading Loading @@ -16638,9 +16639,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc882 }, /* should be patch_alc883() in future */ { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", .patch = patch_alc883 }, { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, {} /* terminator */ }; Loading
sound/pci/hda/patch_conexant.c +111 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include <linux/slab.h> #include <linux/pci.h> #include <sound/core.h> #include <sound/jack.h> #include "hda_codec.h" #include "hda_local.h" Loading @@ -37,7 +39,20 @@ #define CONEXANT_HP_EVENT 0x37 #define CONEXANT_MIC_EVENT 0x38 /* Conexant 5051 specific */ #define CXT5051_SPDIF_OUT 0x1C #define CXT5051_PORTB_EVENT 0x38 #define CXT5051_PORTC_EVENT 0x39 struct conexant_jack { hda_nid_t nid; int type; struct snd_jack *jack; }; struct conexant_spec { Loading Loading @@ -83,6 +98,9 @@ struct conexant_spec { unsigned int spdif_route; /* jack detection */ struct snd_array jacks; /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; struct hda_input_mux private_imux; Loading Loading @@ -329,6 +347,86 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_mux[adc_idx]); } static int conexant_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { struct conexant_spec *spec; struct conexant_jack *jack; const char *name; spec = codec->spec; snd_array_init(&spec->jacks, sizeof(*jack), 32); jack = snd_array_new(&spec->jacks); name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; if (!jack) return -ENOMEM; jack->nid = nid; jack->type = type; return snd_jack_new(codec->bus->card, name, type, &jack->jack); } static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) { struct conexant_spec *spec = codec->spec; struct conexant_jack *jacks = spec->jacks.list; if (jacks) { int i; for (i = 0; i < spec->jacks.used; i++) { if (jacks->nid == nid) { unsigned int present; present = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; present = (present) ? jacks->type : 0 ; snd_jack_report(jacks->jack, present); } jacks++; } } } static int conexant_init_jacks(struct hda_codec *codec) { #ifdef CONFIG_SND_JACK struct conexant_spec *spec = codec->spec; int i; for (i = 0; i < spec->num_init_verbs; i++) { const struct hda_verb *hv; hv = spec->init_verbs[i]; while (hv->nid) { int err = 0; switch (hv->param ^ AC_USRSP_EN) { case CONEXANT_HP_EVENT: err = conexant_add_jack(codec, hv->nid, SND_JACK_HEADPHONE); conexant_report_jack(codec, hv->nid); break; case CXT5051_PORTC_EVENT: case CONEXANT_MIC_EVENT: err = conexant_add_jack(codec, hv->nid, SND_JACK_MICROPHONE); conexant_report_jack(codec, hv->nid); break; } if (err < 0) return err; ++hv; } } #endif return 0; } static int conexant_init(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; Loading @@ -341,6 +439,16 @@ static int conexant_init(struct hda_codec *codec) static void conexant_free(struct hda_codec *codec) { #ifdef CONFIG_SND_JACK struct conexant_spec *spec = codec->spec; if (spec->jacks.list) { struct conexant_jack *jacks = spec->jacks.list; int i; for (i = 0; i < spec->jacks.used; i++) snd_device_free(codec->bus->card, &jacks[i].jack); snd_array_free(&spec->jacks); } #endif kfree(codec->spec); } Loading Loading @@ -1526,9 +1634,6 @@ static int patch_cxt5047(struct hda_codec *codec) /* Conexant 5051 specific */ static hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; #define CXT5051_SPDIF_OUT 0x1C #define CXT5051_PORTB_EVENT 0x38 #define CXT5051_PORTC_EVENT 0x39 static struct hda_channel_mode cxt5051_modes[1] = { { 2, NULL }, Loading Loading @@ -1608,6 +1713,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec) static void cxt5051_hp_unsol_event(struct hda_codec *codec, unsigned int res) { int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; switch (res >> 26) { case CONEXANT_HP_EVENT: cxt5051_hp_automute(codec); Loading @@ -1619,6 +1725,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, cxt5051_portc_automic(codec); break; } conexant_report_jack(codec, nid); } static struct snd_kcontrol_new cxt5051_mixers[] = { Loading Loading @@ -1693,6 +1800,7 @@ static struct hda_verb cxt5051_init_verbs[] = { static int cxt5051_init(struct hda_codec *codec) { conexant_init(codec); conexant_init_jacks(codec); if (codec->patch_ops.unsol_event) { cxt5051_hp_automute(codec); cxt5051_portb_automic(codec); Loading
sound/pci/hda/patch_realtek.c +2 −1 Original line number Diff line number Diff line Loading @@ -8467,6 +8467,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), Loading Loading @@ -16638,9 +16639,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc882 }, /* should be patch_alc883() in future */ { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", .patch = patch_alc883 }, { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, {} /* terminator */ };