aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-11-18 03:32:42 -0500
committerTakashi Iwai <tiwai@suse.de>2008-11-18 03:43:05 -0500
commite4973e1e5a42072ce88736ba0e39e4b8fc6c3c44 (patch)
treeb7cac8500e29d001f0b3e1eeb4539ec43708fc32 /sound
parent5f1e71b1cc2cc788c0f452772e2ce5e7430c40c2 (diff)
ALSA: hda - Create jack detection elements in build_controls
The jack detection input elements should be created in build_controls callback instead of init callback because init can be called multiple times by suspend/resume and power-saving. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_sigmatel.c59
1 files changed, 40 insertions, 19 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 1aa3f6cbcb9..b6cf821434c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1249,10 +1249,13 @@ static const char *slave_sws[] = {
1249}; 1249};
1250 1250
1251static void stac92xx_free_kctls(struct hda_codec *codec); 1251static void stac92xx_free_kctls(struct hda_codec *codec);
1252static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type);
1252 1253
1253static int stac92xx_build_controls(struct hda_codec *codec) 1254static int stac92xx_build_controls(struct hda_codec *codec)
1254{ 1255{
1255 struct sigmatel_spec *spec = codec->spec; 1256 struct sigmatel_spec *spec = codec->spec;
1257 struct auto_pin_cfg *cfg = &spec->autocfg;
1258 hda_nid_t nid;
1256 int err; 1259 int err;
1257 int i; 1260 int i;
1258 1261
@@ -1323,6 +1326,36 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1323 } 1326 }
1324 1327
1325 stac92xx_free_kctls(codec); /* no longer needed */ 1328 stac92xx_free_kctls(codec); /* no longer needed */
1329
1330 /* create jack input elements */
1331 if (spec->hp_detect) {
1332 for (i = 0; i < cfg->hp_outs; i++) {
1333 int type = SND_JACK_HEADPHONE;
1334 nid = cfg->hp_pins[i];
1335 /* jack detection */
1336 if (cfg->hp_outs == i)
1337 type |= SND_JACK_LINEOUT;
1338 err = stac92xx_add_jack(codec, nid, type);
1339 if (err < 0)
1340 return err;
1341 }
1342 }
1343 for (i = 0; i < cfg->line_outs; i++) {
1344 err = stac92xx_add_jack(codec, cfg->line_out_pins[i],
1345 SND_JACK_LINEOUT);
1346 if (err < 0)
1347 return err;
1348 }
1349 for (i = 0; i < AUTO_PIN_LAST; i++) {
1350 nid = cfg->input_pins[i];
1351 if (nid) {
1352 err = stac92xx_add_jack(codec, nid,
1353 SND_JACK_MICROPHONE);
1354 if (err < 0)
1355 return err;
1356 }
1357 }
1358
1326 return 0; 1359 return 0;
1327} 1360}
1328 1361
@@ -3658,6 +3691,7 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
3658static int stac92xx_add_jack(struct hda_codec *codec, 3691static int stac92xx_add_jack(struct hda_codec *codec,
3659 hda_nid_t nid, int type) 3692 hda_nid_t nid, int type)
3660{ 3693{
3694#ifdef CONFIG_SND_JACK
3661 struct sigmatel_spec *spec = codec->spec; 3695 struct sigmatel_spec *spec = codec->spec;
3662 struct sigmatel_jack *jack; 3696 struct sigmatel_jack *jack;
3663 int def_conf = snd_hda_codec_read(codec, nid, 3697 int def_conf = snd_hda_codec_read(codec, nid,
@@ -3681,6 +3715,9 @@ static int stac92xx_add_jack(struct hda_codec *codec,
3681 snd_hda_get_jack_location(def_conf)); 3715 snd_hda_get_jack_location(def_conf));
3682 3716
3683 return snd_jack_new(codec->bus->card, name, type, &jack->jack); 3717 return snd_jack_new(codec->bus->card, name, type, &jack->jack);
3718#else
3719 return 0;
3720#endif
3684} 3721}
3685 3722
3686static int stac92xx_add_event(struct sigmatel_spec *spec, hda_nid_t nid, 3723static int stac92xx_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
@@ -3748,7 +3785,7 @@ static int stac92xx_init(struct hda_codec *codec)
3748{ 3785{
3749 struct sigmatel_spec *spec = codec->spec; 3786 struct sigmatel_spec *spec = codec->spec;
3750 struct auto_pin_cfg *cfg = &spec->autocfg; 3787 struct auto_pin_cfg *cfg = &spec->autocfg;
3751 int i, err; 3788 int i;
3752 3789
3753 snd_hda_sequence_write(codec, spec->init); 3790 snd_hda_sequence_write(codec, spec->init);
3754 3791
@@ -3762,16 +3799,8 @@ static int stac92xx_init(struct hda_codec *codec)
3762 if (spec->hp_detect) { 3799 if (spec->hp_detect) {
3763 /* Enable unsolicited responses on the HP widget */ 3800 /* Enable unsolicited responses on the HP widget */
3764 for (i = 0; i < cfg->hp_outs; i++) { 3801 for (i = 0; i < cfg->hp_outs; i++) {
3765 int type = SND_JACK_HEADPHONE;
3766 hda_nid_t nid = cfg->hp_pins[i]; 3802 hda_nid_t nid = cfg->hp_pins[i];
3767 enable_pin_detect(codec, nid, STAC_HP_EVENT | nid); 3803 enable_pin_detect(codec, nid, STAC_HP_EVENT | nid);
3768 /* jack detection */
3769 if (cfg->hp_outs == i)
3770 type |= SND_JACK_LINEOUT;
3771 err = stac92xx_add_jack(codec, nid, type);
3772 if (err < 0)
3773 return err;
3774
3775 } 3804 }
3776 /* force to enable the first line-out; the others are set up 3805 /* force to enable the first line-out; the others are set up
3777 * in unsol_event 3806 * in unsol_event
@@ -3785,12 +3814,6 @@ static int stac92xx_init(struct hda_codec *codec)
3785 stac92xx_auto_init_multi_out(codec); 3814 stac92xx_auto_init_multi_out(codec);
3786 stac92xx_auto_init_hp_out(codec); 3815 stac92xx_auto_init_hp_out(codec);
3787 } 3816 }
3788 for (i = 0; i < cfg->line_outs; i++) {
3789 err = stac92xx_add_jack(codec,
3790 cfg->line_out_pins[i], SND_JACK_LINEOUT);
3791 if (err < 0)
3792 return err;
3793 }
3794 for (i = 0; i < AUTO_PIN_LAST; i++) { 3817 for (i = 0; i < AUTO_PIN_LAST; i++) {
3795 hda_nid_t nid = cfg->input_pins[i]; 3818 hda_nid_t nid = cfg->input_pins[i];
3796 if (nid) { 3819 if (nid) {
@@ -3807,10 +3830,6 @@ static int stac92xx_init(struct hda_codec *codec)
3807 } 3830 }
3808 pinctl |= AC_PINCTL_IN_EN; 3831 pinctl |= AC_PINCTL_IN_EN;
3809 stac92xx_auto_set_pinctl(codec, nid, pinctl); 3832 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3810 err = stac92xx_add_jack(codec, nid,
3811 SND_JACK_MICROPHONE);
3812 if (err < 0)
3813 return err;
3814 enable_pin_detect(codec, nid, STAC_INSERT_EVENT | nid); 3833 enable_pin_detect(codec, nid, STAC_INSERT_EVENT | nid);
3815 } 3834 }
3816 } 3835 }
@@ -3855,6 +3874,7 @@ static int stac92xx_init(struct hda_codec *codec)
3855 3874
3856static void stac92xx_free_jacks(struct hda_codec *codec) 3875static void stac92xx_free_jacks(struct hda_codec *codec)
3857{ 3876{
3877#ifdef CONFIG_SND_JACK
3858 struct sigmatel_spec *spec = codec->spec; 3878 struct sigmatel_spec *spec = codec->spec;
3859 if (spec->jacks.list) { 3879 if (spec->jacks.list) {
3860 struct sigmatel_jack *jacks = spec->jacks.list; 3880 struct sigmatel_jack *jacks = spec->jacks.list;
@@ -3863,6 +3883,7 @@ static void stac92xx_free_jacks(struct hda_codec *codec)
3863 snd_device_free(codec->bus->card, &jacks[i].jack); 3883 snd_device_free(codec->bus->card, &jacks[i].jack);
3864 } 3884 }
3865 snd_array_free(&spec->jacks); 3885 snd_array_free(&spec->jacks);
3886#endif
3866} 3887}
3867 3888
3868static void stac92xx_free_kctls(struct hda_codec *codec) 3889static void stac92xx_free_kctls(struct hda_codec *codec)