aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-03-03 08:40:14 -0500
committerTakashi Iwai <tiwai@suse.de>2011-03-03 08:40:14 -0500
commitcd372fb3befde3bceef3fdcbc550dde50c894e36 (patch)
tree300fec172522d11408ccd8086f7789cdcd2a8509 /sound/pci
parentd207df2df064c19a2cf4eac8f887351fe5ce526e (diff)
ALSA: hda - Make common input-jack helper functions
Since multiple codec drivers already use the input-jack stuff, let's make common helper functions to reduce the duplicated codes. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c105
-rw-r--r--sound/pci/hda/hda_codec.h5
-rw-r--r--sound/pci/hda/hda_local.h24
-rw-r--r--sound/pci/hda/patch_conexant.c124
-rw-r--r--sound/pci/hda/patch_realtek.c94
-rw-r--r--sound/pci/hda/patch_sigmatel.c85
6 files changed, 165 insertions, 272 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index ae5c5d5e4b7c..2c79e96d0324 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -29,6 +29,7 @@
29#include <sound/asoundef.h> 29#include <sound/asoundef.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/jack.h>
32#include "hda_local.h" 33#include "hda_local.h"
33#include "hda_beep.h" 34#include "hda_beep.h"
34#include <sound/hda_hwdep.h> 35#include <sound/hda_hwdep.h>
@@ -4959,5 +4960,109 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen)
4959} 4960}
4960EXPORT_SYMBOL_HDA(snd_print_pcm_bits); 4961EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
4961 4962
4963#ifdef CONFIG_SND_HDA_INPUT_JACK
4964/*
4965 * Input-jack notification support
4966 */
4967struct hda_jack_item {
4968 hda_nid_t nid;
4969 int type;
4970 struct snd_jack *jack;
4971};
4972
4973static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid,
4974 int type)
4975{
4976 switch (type) {
4977 case SND_JACK_HEADPHONE:
4978 return "Headphone";
4979 case SND_JACK_MICROPHONE:
4980 return "Mic";
4981 case SND_JACK_LINEOUT:
4982 return "Line-out";
4983 case SND_JACK_HEADSET:
4984 return "Headset";
4985 default:
4986 return "Misc";
4987 }
4988}
4989
4990static void hda_free_jack_priv(struct snd_jack *jack)
4991{
4992 struct hda_jack_item *jacks = jack->private_data;
4993 jacks->nid = 0;
4994 jacks->jack = NULL;
4995}
4996
4997int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
4998 const char *name)
4999{
5000 struct hda_jack_item *jack;
5001 int err;
5002
5003 snd_array_init(&codec->jacks, sizeof(*jack), 32);
5004 jack = snd_array_new(&codec->jacks);
5005 if (!jack)
5006 return -ENOMEM;
5007
5008 jack->nid = nid;
5009 jack->type = type;
5010 if (!name)
5011 name = get_jack_default_name(codec, nid, type);
5012 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
5013 if (err < 0) {
5014 jack->nid = 0;
5015 return err;
5016 }
5017 jack->jack->private_data = jack;
5018 jack->jack->private_free = hda_free_jack_priv;
5019 return 0;
5020}
5021EXPORT_SYMBOL_HDA(snd_hda_input_jack_add);
5022
5023void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid)
5024{
5025 struct hda_jack_item *jacks = codec->jacks.list;
5026 int i;
5027
5028 if (!jacks)
5029 return;
5030
5031 for (i = 0; i < codec->jacks.used; i++, jacks++) {
5032 unsigned int pin_ctl;
5033 unsigned int present;
5034 int type;
5035
5036 if (jacks->nid != nid)
5037 continue;
5038 present = snd_hda_jack_detect(codec, nid);
5039 type = jacks->type;
5040 if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) {
5041 pin_ctl = snd_hda_codec_read(codec, nid, 0,
5042 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5043 type = (pin_ctl & AC_PINCTL_HP_EN) ?
5044 SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
5045 }
5046 snd_jack_report(jacks->jack, present ? type : 0);
5047 }
5048}
5049EXPORT_SYMBOL_HDA(snd_hda_input_jack_report);
5050
5051/* free jack instances manually when clearing/reconfiguring */
5052void snd_hda_input_jack_free(struct hda_codec *codec)
5053{
5054 if (!codec->bus->shutdown && codec->jacks.list) {
5055 struct hda_jack_item *jacks = codec->jacks.list;
5056 int i;
5057 for (i = 0; i < codec->jacks.used; i++, jacks++) {
5058 if (jacks->jack)
5059 snd_device_free(codec->bus->card, jacks->jack);
5060 }
5061 }
5062 snd_array_free(&codec->jacks);
5063}
5064EXPORT_SYMBOL_HDA(snd_hda_input_jack_free);
5065#endif /* CONFIG_SND_HDA_INPUT_JACK */
5066
4962MODULE_DESCRIPTION("HDA codec core"); 5067MODULE_DESCRIPTION("HDA codec core");
4963MODULE_LICENSE("GPL"); 5068MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index fdf8d44f8b6b..e46d5420a9f2 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -866,6 +866,11 @@ struct hda_codec {
866 /* codec-specific additional proc output */ 866 /* codec-specific additional proc output */
867 void (*proc_widget_hook)(struct snd_info_buffer *buffer, 867 void (*proc_widget_hook)(struct snd_info_buffer *buffer,
868 struct hda_codec *codec, hda_nid_t nid); 868 struct hda_codec *codec, hda_nid_t nid);
869
870#ifdef CONFIG_SND_HDA_INPUT_JACK
871 /* jack detection */
872 struct snd_array jacks;
873#endif
869}; 874};
870 875
871/* direction */ 876/* direction */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 3ab5e7a303db..ff5e2ac2239a 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -656,4 +656,28 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
656#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 656#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
657void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); 657void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
658 658
659/*
660 * Input-jack notification support
661 */
662#ifdef CONFIG_SND_HDA_INPUT_JACK
663int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
664 const char *name);
665void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid);
666void snd_hda_input_jack_free(struct hda_codec *codec);
667#else /* CONFIG_SND_HDA_INPUT_JACK */
668static inline int snd_hda_input_jack_add(struct hda_codec *codec,
669 hda_nid_t nid, int type,
670 const char *name)
671{
672 return 0;
673}
674static inline void snd_hda_input_jack_report(struct hda_codec *codec,
675 hda_nid_t nid)
676{
677}
678static inline void snd_hda_input_jack_free(struct hda_codec *codec)
679{
680}
681#endif /* CONFIG_SND_HDA_INPUT_JACK */
682
659#endif /* __SOUND_HDA_LOCAL_H */ 683#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 4d5004e693f0..d08cf31596f3 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -49,14 +49,6 @@
49#define AUTO_MIC_PORTB (1 << 1) 49#define AUTO_MIC_PORTB (1 << 1)
50#define AUTO_MIC_PORTC (1 << 2) 50#define AUTO_MIC_PORTC (1 << 2)
51 51
52struct conexant_jack {
53
54 hda_nid_t nid;
55 int type;
56 struct snd_jack *jack;
57
58};
59
60struct pin_dac_pair { 52struct pin_dac_pair {
61 hda_nid_t pin; 53 hda_nid_t pin;
62 hda_nid_t dac; 54 hda_nid_t dac;
@@ -111,9 +103,6 @@ struct conexant_spec {
111 103
112 unsigned int spdif_route; 104 unsigned int spdif_route;
113 105
114 /* jack detection */
115 struct snd_array jacks;
116
117 /* dynamic controls, init_verbs and input_mux */ 106 /* dynamic controls, init_verbs and input_mux */
118 struct auto_pin_cfg autocfg; 107 struct auto_pin_cfg autocfg;
119 struct hda_input_mux private_imux; 108 struct hda_input_mux private_imux;
@@ -393,71 +382,9 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
393 &spec->cur_mux[adc_idx]); 382 &spec->cur_mux[adc_idx]);
394} 383}
395 384
396#ifdef CONFIG_SND_HDA_INPUT_JACK
397static void conexant_free_jack_priv(struct snd_jack *jack)
398{
399 struct conexant_jack *jacks = jack->private_data;
400 jacks->nid = 0;
401 jacks->jack = NULL;
402}
403
404static int conexant_add_jack(struct hda_codec *codec,
405 hda_nid_t nid, int type)
406{
407 struct conexant_spec *spec;
408 struct conexant_jack *jack;
409 const char *name;
410 int i, err;
411
412 spec = codec->spec;
413 snd_array_init(&spec->jacks, sizeof(*jack), 32);
414
415 jack = spec->jacks.list;
416 for (i = 0; i < spec->jacks.used; i++, jack++)
417 if (jack->nid == nid)
418 return 0 ; /* already present */
419
420 jack = snd_array_new(&spec->jacks);
421 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
422
423 if (!jack)
424 return -ENOMEM;
425
426 jack->nid = nid;
427 jack->type = type;
428
429 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
430 if (err < 0)
431 return err;
432 jack->jack->private_data = jack;
433 jack->jack->private_free = conexant_free_jack_priv;
434 return 0;
435}
436
437static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
438{
439 struct conexant_spec *spec = codec->spec;
440 struct conexant_jack *jacks = spec->jacks.list;
441
442 if (jacks) {
443 int i;
444 for (i = 0; i < spec->jacks.used; i++) {
445 if (jacks->nid == nid) {
446 unsigned int present;
447 present = snd_hda_jack_detect(codec, nid);
448
449 present = (present) ? jacks->type : 0 ;
450
451 snd_jack_report(jacks->jack,
452 present);
453 }
454 jacks++;
455 }
456 }
457}
458
459static int conexant_init_jacks(struct hda_codec *codec) 385static int conexant_init_jacks(struct hda_codec *codec)
460{ 386{
387#ifdef CONFIG_SND_HDA_INPUT_JACK
461 struct conexant_spec *spec = codec->spec; 388 struct conexant_spec *spec = codec->spec;
462 int i; 389 int i;
463 390
@@ -469,15 +396,15 @@ static int conexant_init_jacks(struct hda_codec *codec)
469 int err = 0; 396 int err = 0;
470 switch (hv->param ^ AC_USRSP_EN) { 397 switch (hv->param ^ AC_USRSP_EN) {
471 case CONEXANT_HP_EVENT: 398 case CONEXANT_HP_EVENT:
472 err = conexant_add_jack(codec, hv->nid, 399 err = snd_hda_input_jack_add(codec, hv->nid,
473 SND_JACK_HEADPHONE); 400 SND_JACK_HEADPHONE, NULL);
474 conexant_report_jack(codec, hv->nid); 401 snd_hda_input_jack_report(codec, hv->nid);
475 break; 402 break;
476 case CXT5051_PORTC_EVENT: 403 case CXT5051_PORTC_EVENT:
477 case CONEXANT_MIC_EVENT: 404 case CONEXANT_MIC_EVENT:
478 err = conexant_add_jack(codec, hv->nid, 405 err = snd_hda_input_jack_add(codec, hv->nid,
479 SND_JACK_MICROPHONE); 406 SND_JACK_MICROPHONE, NULL);
480 conexant_report_jack(codec, hv->nid); 407 snd_hda_input_jack_report(codec, hv->nid);
481 break; 408 break;
482 } 409 }
483 if (err < 0) 410 if (err < 0)
@@ -485,19 +412,9 @@ static int conexant_init_jacks(struct hda_codec *codec)
485 ++hv; 412 ++hv;
486 } 413 }
487 } 414 }
488 return 0; 415#endif /* CONFIG_SND_HDA_INPUT_JACK */
489
490}
491#else
492static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
493{
494}
495
496static inline int conexant_init_jacks(struct hda_codec *codec)
497{
498 return 0; 416 return 0;
499} 417}
500#endif
501 418
502static int conexant_init(struct hda_codec *codec) 419static int conexant_init(struct hda_codec *codec)
503{ 420{
@@ -511,18 +428,7 @@ static int conexant_init(struct hda_codec *codec)
511 428
512static void conexant_free(struct hda_codec *codec) 429static void conexant_free(struct hda_codec *codec)
513{ 430{
514#ifdef CONFIG_SND_HDA_INPUT_JACK 431 snd_hda_input_jack_free(codec);
515 struct conexant_spec *spec = codec->spec;
516 if (spec->jacks.list) {
517 struct conexant_jack *jacks = spec->jacks.list;
518 int i;
519 for (i = 0; i < spec->jacks.used; i++, jacks++) {
520 if (jacks->jack)
521 snd_device_free(codec->bus->card, jacks->jack);
522 }
523 snd_array_free(&spec->jacks);
524 }
525#endif
526 snd_hda_detach_beep_device(codec); 432 snd_hda_detach_beep_device(codec);
527 kfree(codec->spec); 433 kfree(codec->spec);
528} 434}
@@ -1787,7 +1693,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1787 cxt5051_portc_automic(codec); 1693 cxt5051_portc_automic(codec);
1788 break; 1694 break;
1789 } 1695 }
1790 conexant_report_jack(codec, nid); 1696 snd_hda_input_jack_report(codec, nid);
1791} 1697}
1792 1698
1793static struct snd_kcontrol_new cxt5051_playback_mixers[] = { 1699static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
@@ -1959,10 +1865,8 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1959 snd_hda_codec_write(codec, nid, 0, 1865 snd_hda_codec_write(codec, nid, 0,
1960 AC_VERB_SET_UNSOLICITED_ENABLE, 1866 AC_VERB_SET_UNSOLICITED_ENABLE,
1961 AC_USRSP_EN | event); 1867 AC_USRSP_EN | event);
1962#ifdef CONFIG_SND_HDA_INPUT_JACK 1868 snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL);
1963 conexant_add_jack(codec, nid, SND_JACK_MICROPHONE); 1869 snd_hda_input_jack_report(codec, nid);
1964 conexant_report_jack(codec, nid);
1965#endif
1966} 1870}
1967 1871
1968static struct hda_verb cxt5051_ideapad_init_verbs[] = { 1872static struct hda_verb cxt5051_ideapad_init_verbs[] = {
@@ -3477,11 +3381,11 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3477 switch (res >> 26) { 3381 switch (res >> 26) {
3478 case CONEXANT_HP_EVENT: 3382 case CONEXANT_HP_EVENT:
3479 cx_auto_hp_automute(codec); 3383 cx_auto_hp_automute(codec);
3480 conexant_report_jack(codec, nid); 3384 snd_hda_input_jack_report(codec, nid);
3481 break; 3385 break;
3482 case CONEXANT_MIC_EVENT: 3386 case CONEXANT_MIC_EVENT:
3483 cx_auto_automic(codec); 3387 cx_auto_automic(codec);
3484 conexant_report_jack(codec, nid); 3388 snd_hda_input_jack_report(codec, nid);
3485 break; 3389 break;
3486 } 3390 }
3487} 3391}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 96cb442dc1d1..f6c344126b83 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -282,12 +282,6 @@ struct alc_mic_route {
282 unsigned char amix_idx; 282 unsigned char amix_idx;
283}; 283};
284 284
285struct alc_jack {
286 hda_nid_t nid;
287 int type;
288 struct snd_jack *jack;
289};
290
291#define MUX_IDX_UNDEF ((unsigned char)-1) 285#define MUX_IDX_UNDEF ((unsigned char)-1)
292 286
293struct alc_customize_define { 287struct alc_customize_define {
@@ -366,9 +360,6 @@ struct alc_spec {
366 /* PCM information */ 360 /* PCM information */
367 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 361 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
368 362
369 /* jack detection */
370 struct snd_array jacks;
371
372 /* dynamic controls, init_verbs and input_mux */ 363 /* dynamic controls, init_verbs and input_mux */
373 struct auto_pin_cfg autocfg; 364 struct auto_pin_cfg autocfg;
374 struct alc_customize_define cdefine; 365 struct alc_customize_define cdefine;
@@ -1032,94 +1023,32 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1032 alc_fix_pll(codec); 1023 alc_fix_pll(codec);
1033} 1024}
1034 1025
1035#ifdef CONFIG_SND_HDA_INPUT_JACK
1036static void alc_free_jack_priv(struct snd_jack *jack)
1037{
1038 struct alc_jack *jacks = jack->private_data;
1039 jacks->nid = 0;
1040 jacks->jack = NULL;
1041}
1042
1043static int alc_add_jack(struct hda_codec *codec,
1044 hda_nid_t nid, int type)
1045{
1046 struct alc_spec *spec;
1047 struct alc_jack *jack;
1048 const char *name;
1049 int err;
1050
1051 spec = codec->spec;
1052 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1053 jack = snd_array_new(&spec->jacks);
1054 if (!jack)
1055 return -ENOMEM;
1056
1057 jack->nid = nid;
1058 jack->type = type;
1059 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1060
1061 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1062 if (err < 0)
1063 return err;
1064 jack->jack->private_data = jack;
1065 jack->jack->private_free = alc_free_jack_priv;
1066 return 0;
1067}
1068
1069static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1070{
1071 struct alc_spec *spec = codec->spec;
1072 struct alc_jack *jacks = spec->jacks.list;
1073
1074 if (jacks) {
1075 int i;
1076 for (i = 0; i < spec->jacks.used; i++) {
1077 if (jacks->nid == nid) {
1078 unsigned int present;
1079 present = snd_hda_jack_detect(codec, nid);
1080
1081 present = (present) ? jacks->type : 0;
1082
1083 snd_jack_report(jacks->jack, present);
1084 }
1085 jacks++;
1086 }
1087 }
1088}
1089
1090static int alc_init_jacks(struct hda_codec *codec) 1026static int alc_init_jacks(struct hda_codec *codec)
1091{ 1027{
1028#ifdef CONFIG_SND_HDA_INPUT_JACK
1092 struct alc_spec *spec = codec->spec; 1029 struct alc_spec *spec = codec->spec;
1093 int err; 1030 int err;
1094 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 1031 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1095 unsigned int mic_nid = spec->ext_mic.pin; 1032 unsigned int mic_nid = spec->ext_mic.pin;
1096 1033
1097 if (hp_nid) { 1034 if (hp_nid) {
1098 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); 1035 err = snd_hda_input_jack_add(codec, hp_nid,
1036 SND_JACK_HEADPHONE, NULL);
1099 if (err < 0) 1037 if (err < 0)
1100 return err; 1038 return err;
1101 alc_report_jack(codec, hp_nid); 1039 snd_hda_input_jack_report(codec, hp_nid);
1102 } 1040 }
1103 1041
1104 if (mic_nid) { 1042 if (mic_nid) {
1105 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); 1043 err = snd_hda_input_jack_add(codec, mic_nid,
1044 SND_JACK_MICROPHONE, NULL);
1106 if (err < 0) 1045 if (err < 0)
1107 return err; 1046 return err;
1108 alc_report_jack(codec, mic_nid); 1047 snd_hda_input_jack_report(codec, mic_nid);
1109 } 1048 }
1110 1049#endif /* CONFIG_SND_HDA_INPUT_JACK */
1111 return 0;
1112}
1113#else
1114static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1115{
1116}
1117
1118static inline int alc_init_jacks(struct hda_codec *codec)
1119{
1120 return 0; 1050 return 0;
1121} 1051}
1122#endif
1123 1052
1124static void alc_automute_speaker(struct hda_codec *codec, int pinctl) 1053static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1125{ 1054{
@@ -1133,7 +1062,7 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1133 nid = spec->autocfg.hp_pins[i]; 1062 nid = spec->autocfg.hp_pins[i];
1134 if (!nid) 1063 if (!nid)
1135 break; 1064 break;
1136 alc_report_jack(codec, nid); 1065 snd_hda_input_jack_report(codec, nid);
1137 spec->jack_present |= snd_hda_jack_detect(codec, nid); 1066 spec->jack_present |= snd_hda_jack_detect(codec, nid);
1138 } 1067 }
1139 1068
@@ -1240,7 +1169,7 @@ static void alc_mic_automute(struct hda_codec *codec)
1240 AC_VERB_SET_CONNECT_SEL, 1169 AC_VERB_SET_CONNECT_SEL,
1241 alive->mux_idx); 1170 alive->mux_idx);
1242 } 1171 }
1243 alc_report_jack(codec, spec->ext_mic.pin); 1172 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1244 1173
1245 /* FIXME: analog mixer */ 1174 /* FIXME: analog mixer */
1246} 1175}
@@ -4283,6 +4212,7 @@ static void alc_free(struct hda_codec *codec)
4283 return; 4212 return;
4284 4213
4285 alc_shutup(codec); 4214 alc_shutup(codec);
4215 snd_hda_input_jack_free(codec);
4286 alc_free_kctls(codec); 4216 alc_free_kctls(codec);
4287 kfree(spec); 4217 kfree(spec);
4288 snd_hda_detach_beep_device(codec); 4218 snd_hda_detach_beep_device(codec);
@@ -14494,7 +14424,7 @@ static void alc269_speaker_automute(struct hda_codec *codec)
14494 HDA_AMP_MUTE, bits); 14424 HDA_AMP_MUTE, bits);
14495 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14425 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14496 HDA_AMP_MUTE, bits); 14426 HDA_AMP_MUTE, bits);
14497 alc_report_jack(codec, nid); 14427 snd_hda_input_jack_report(codec, nid);
14498} 14428}
14499 14429
14500/* unsolicited event for HP jack sensing */ 14430/* unsolicited event for HP jack sensing */
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index bd7b123f6440..8fe5608c5f29 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -180,12 +180,6 @@ struct sigmatel_event {
180 int data; 180 int data;
181}; 181};
182 182
183struct sigmatel_jack {
184 hda_nid_t nid;
185 int type;
186 struct snd_jack *jack;
187};
188
189struct sigmatel_mic_route { 183struct sigmatel_mic_route {
190 hda_nid_t pin; 184 hda_nid_t pin;
191 signed char mux_idx; 185 signed char mux_idx;
@@ -229,9 +223,6 @@ struct sigmatel_spec {
229 hda_nid_t *pwr_nids; 223 hda_nid_t *pwr_nids;
230 hda_nid_t *dac_list; 224 hda_nid_t *dac_list;
231 225
232 /* jack detection */
233 struct snd_array jacks;
234
235 /* events */ 226 /* events */
236 struct snd_array events; 227 struct snd_array events;
237 228
@@ -4054,21 +4045,10 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4054 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ 4045 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
4055} 4046}
4056 4047
4057#ifdef CONFIG_SND_HDA_INPUT_JACK
4058static void stac92xx_free_jack_priv(struct snd_jack *jack)
4059{
4060 struct sigmatel_jack *jacks = jack->private_data;
4061 jacks->nid = 0;
4062 jacks->jack = NULL;
4063}
4064#endif
4065
4066static int stac92xx_add_jack(struct hda_codec *codec, 4048static int stac92xx_add_jack(struct hda_codec *codec,
4067 hda_nid_t nid, int type) 4049 hda_nid_t nid, int type)
4068{ 4050{
4069#ifdef CONFIG_SND_HDA_INPUT_JACK 4051#ifdef CONFIG_SND_HDA_INPUT_JACK
4070 struct sigmatel_spec *spec = codec->spec;
4071 struct sigmatel_jack *jack;
4072 int def_conf = snd_hda_codec_get_pincfg(codec, nid); 4052 int def_conf = snd_hda_codec_get_pincfg(codec, nid);
4073 int connectivity = get_defcfg_connect(def_conf); 4053 int connectivity = get_defcfg_connect(def_conf);
4074 char name[32]; 4054 char name[32];
@@ -4077,26 +4057,15 @@ static int stac92xx_add_jack(struct hda_codec *codec,
4077 if (connectivity && connectivity != AC_JACK_PORT_FIXED) 4057 if (connectivity && connectivity != AC_JACK_PORT_FIXED)
4078 return 0; 4058 return 0;
4079 4059
4080 snd_array_init(&spec->jacks, sizeof(*jack), 32);
4081 jack = snd_array_new(&spec->jacks);
4082 if (!jack)
4083 return -ENOMEM;
4084 jack->nid = nid;
4085 jack->type = type;
4086
4087 snprintf(name, sizeof(name), "%s at %s %s Jack", 4060 snprintf(name, sizeof(name), "%s at %s %s Jack",
4088 snd_hda_get_jack_type(def_conf), 4061 snd_hda_get_jack_type(def_conf),
4089 snd_hda_get_jack_connectivity(def_conf), 4062 snd_hda_get_jack_connectivity(def_conf),
4090 snd_hda_get_jack_location(def_conf)); 4063 snd_hda_get_jack_location(def_conf));
4091 4064
4092 err = snd_jack_new(codec->bus->card, name, type, &jack->jack); 4065 err = snd_hda_input_jack_add(codec, nid, type, name);
4093 if (err < 0) { 4066 if (err < 0)
4094 jack->nid = 0;
4095 return err; 4067 return err;
4096 } 4068#endif /* CONFIG_SND_HDA_INPUT_JACK */
4097 jack->jack->private_data = jack;
4098 jack->jack->private_free = stac92xx_free_jack_priv;
4099#endif
4100 return 0; 4069 return 0;
4101} 4070}
4102 4071
@@ -4399,23 +4368,6 @@ static int stac92xx_init(struct hda_codec *codec)
4399 return 0; 4368 return 0;
4400} 4369}
4401 4370
4402static void stac92xx_free_jacks(struct hda_codec *codec)
4403{
4404#ifdef CONFIG_SND_HDA_INPUT_JACK
4405 /* free jack instances manually when clearing/reconfiguring */
4406 struct sigmatel_spec *spec = codec->spec;
4407 if (!codec->bus->shutdown && spec->jacks.list) {
4408 struct sigmatel_jack *jacks = spec->jacks.list;
4409 int i;
4410 for (i = 0; i < spec->jacks.used; i++, jacks++) {
4411 if (jacks->jack)
4412 snd_device_free(codec->bus->card, jacks->jack);
4413 }
4414 }
4415 snd_array_free(&spec->jacks);
4416#endif
4417}
4418
4419static void stac92xx_free_kctls(struct hda_codec *codec) 4371static void stac92xx_free_kctls(struct hda_codec *codec)
4420{ 4372{
4421 struct sigmatel_spec *spec = codec->spec; 4373 struct sigmatel_spec *spec = codec->spec;
@@ -4449,7 +4401,7 @@ static void stac92xx_free(struct hda_codec *codec)
4449 return; 4401 return;
4450 4402
4451 stac92xx_shutup(codec); 4403 stac92xx_shutup(codec);
4452 stac92xx_free_jacks(codec); 4404 snd_hda_input_jack_free(codec);
4453 snd_array_free(&spec->events); 4405 snd_array_free(&spec->events);
4454 4406
4455 kfree(spec); 4407 kfree(spec);
@@ -4667,33 +4619,6 @@ static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
4667 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid)); 4619 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
4668} 4620}
4669 4621
4670static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4671{
4672 struct sigmatel_spec *spec = codec->spec;
4673 struct sigmatel_jack *jacks = spec->jacks.list;
4674
4675 if (jacks) {
4676 int i;
4677 for (i = 0; i < spec->jacks.used; i++) {
4678 if (jacks->nid == nid) {
4679 unsigned int pin_ctl =
4680 snd_hda_codec_read(codec, nid,
4681 0, AC_VERB_GET_PIN_WIDGET_CONTROL,
4682 0x00);
4683 int type = jacks->type;
4684 if (type == (SND_JACK_LINEOUT
4685 | SND_JACK_HEADPHONE))
4686 type = (pin_ctl & AC_PINCTL_HP_EN)
4687 ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
4688 snd_jack_report(jacks->jack,
4689 get_pin_presence(codec, nid)
4690 ? type : 0);
4691 }
4692 jacks++;
4693 }
4694 }
4695}
4696
4697/* get the pin connection (fixed, none, etc) */ 4622/* get the pin connection (fixed, none, etc) */
4698static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) 4623static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
4699{ 4624{
@@ -4782,7 +4707,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4782 case STAC_PWR_EVENT: 4707 case STAC_PWR_EVENT:
4783 if (spec->num_pwrs > 0) 4708 if (spec->num_pwrs > 0)
4784 stac92xx_pin_sense(codec, event->nid); 4709 stac92xx_pin_sense(codec, event->nid);
4785 stac92xx_report_jack(codec, event->nid); 4710 snd_hda_input_jack_report(codec, event->nid);
4786 4711
4787 switch (codec->subsystem_id) { 4712 switch (codec->subsystem_id) {
4788 case 0x103c308f: 4713 case 0x103c308f: