diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-11-18 03:32:42 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-11-18 03:43:05 -0500 |
commit | e4973e1e5a42072ce88736ba0e39e4b8fc6c3c44 (patch) | |
tree | b7cac8500e29d001f0b3e1eeb4539ec43708fc32 /sound | |
parent | 5f1e71b1cc2cc788c0f452772e2ce5e7430c40c2 (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.c | 59 |
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 | ||
1251 | static void stac92xx_free_kctls(struct hda_codec *codec); | 1251 | static void stac92xx_free_kctls(struct hda_codec *codec); |
1252 | static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type); | ||
1252 | 1253 | ||
1253 | static int stac92xx_build_controls(struct hda_codec *codec) | 1254 | static 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, | |||
3658 | static int stac92xx_add_jack(struct hda_codec *codec, | 3691 | static 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 | ||
3686 | static int stac92xx_add_event(struct sigmatel_spec *spec, hda_nid_t nid, | 3723 | static 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 | ||
3856 | static void stac92xx_free_jacks(struct hda_codec *codec) | 3875 | static 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 | ||
3868 | static void stac92xx_free_kctls(struct hda_codec *codec) | 3889 | static void stac92xx_free_kctls(struct hda_codec *codec) |