aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-07-29 08:23:09 -0400
committerTakashi Iwai <tiwai@suse.de>2009-07-29 08:28:37 -0400
commit62558ce15759ee93223132258588320967e1e521 (patch)
treef2c7f7b7fb63105ce56e11934fb712ce76a86c44 /sound/pci/hda/patch_sigmatel.c
parent50c62f068ee67b5a0178855f502f4ea2ee931eed (diff)
ALSA: hda - Avoid overwrite of jack events with STAC/IDT
Since only one event can be associated to a (pin) widget, it's safer to avoid the multiple mapping. This patch fixes the behavior of the STAC/IDT codec driver. Now stac_get_event() doesn't take the type argument but simply returns the first hit element. Then enable_pin_detect() checks the validity of the type, and returns non-zero only if a valid entry. The caller can call stac_issue_unsol_event() after checking the return value. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 66b1f3cfc871..307e86ceede1 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2620,8 +2620,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
2620 return 0; 2620 return 0;
2621} 2621}
2622 2622
2623static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, 2623static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid);
2624 unsigned char type);
2625 2624
2626static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, 2625static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2627 struct snd_ctl_elem_value *ucontrol) 2626 struct snd_ctl_elem_value *ucontrol)
@@ -2635,7 +2634,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2635 /* check to be sure that the ports are upto date with 2634 /* check to be sure that the ports are upto date with
2636 * switch changes 2635 * switch changes
2637 */ 2636 */
2638 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); 2637 stac_issue_unsol_event(codec, nid);
2639 2638
2640 return 1; 2639 return 1;
2641} 2640}
@@ -2768,7 +2767,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2768 * appropriately according to the pin direction 2767 * appropriately according to the pin direction
2769 */ 2768 */
2770 if (spec->hp_detect) 2769 if (spec->hp_detect)
2771 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); 2770 stac_issue_unsol_event(codec, nid);
2772 2771
2773 return 1; 2772 return 1;
2774} 2773}
@@ -4107,14 +4106,14 @@ static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
4107} 4106}
4108 4107
4109static struct sigmatel_event *stac_get_event(struct hda_codec *codec, 4108static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
4110 hda_nid_t nid, unsigned char type) 4109 hda_nid_t nid)
4111{ 4110{
4112 struct sigmatel_spec *spec = codec->spec; 4111 struct sigmatel_spec *spec = codec->spec;
4113 struct sigmatel_event *event = spec->events.list; 4112 struct sigmatel_event *event = spec->events.list;
4114 int i; 4113 int i;
4115 4114
4116 for (i = 0; i < spec->events.used; i++, event++) { 4115 for (i = 0; i < spec->events.used; i++, event++) {
4117 if (event->nid == nid && event->type == type) 4116 if (event->nid == nid)
4118 return event; 4117 return event;
4119 } 4118 }
4120 return NULL; 4119 return NULL;
@@ -4134,24 +4133,32 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
4134 return NULL; 4133 return NULL;
4135} 4134}
4136 4135
4137static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, 4136/* check if given nid is a valid pin and no other events are assigned
4138 unsigned int type) 4137 * to it. If OK, assign the event, set the unsol flag, and returns 1.
4138 * Otherwise, returns zero.
4139 */
4140static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
4141 unsigned int type)
4139{ 4142{
4140 struct sigmatel_event *event; 4143 struct sigmatel_event *event;
4141 int tag; 4144 int tag;
4142 4145
4143 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) 4146 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
4144 return; 4147 return 0;
4145 event = stac_get_event(codec, nid, type); 4148 event = stac_get_event(codec, nid);
4146 if (event) 4149 if (event) {
4150 if (event->type != type)
4151 return 0;
4147 tag = event->tag; 4152 tag = event->tag;
4148 else 4153 } else {
4149 tag = stac_add_event(codec->spec, nid, type, 0); 4154 tag = stac_add_event(codec->spec, nid, type, 0);
4150 if (tag < 0) 4155 if (tag < 0)
4151 return; 4156 return 0;
4157 }
4152 snd_hda_codec_write_cache(codec, nid, 0, 4158 snd_hda_codec_write_cache(codec, nid, 0,
4153 AC_VERB_SET_UNSOLICITED_ENABLE, 4159 AC_VERB_SET_UNSOLICITED_ENABLE,
4154 AC_USRSP_EN | tag); 4160 AC_USRSP_EN | tag);
4161 return 1;
4155} 4162}
4156 4163
4157static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) 4164static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
@@ -4250,8 +4257,7 @@ static int stac92xx_init(struct hda_codec *codec)
4250 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], 4257 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
4251 AC_PINCTL_OUT_EN); 4258 AC_PINCTL_OUT_EN);
4252 /* fake event to set up pins */ 4259 /* fake event to set up pins */
4253 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], 4260 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
4254 STAC_HP_EVENT);
4255 } else { 4261 } else {
4256 stac92xx_auto_init_multi_out(codec); 4262 stac92xx_auto_init_multi_out(codec);
4257 stac92xx_auto_init_hp_out(codec); 4263 stac92xx_auto_init_hp_out(codec);
@@ -4284,10 +4290,9 @@ static int stac92xx_init(struct hda_codec *codec)
4284 } 4290 }
4285 conf = snd_hda_codec_get_pincfg(codec, nid); 4291 conf = snd_hda_codec_get_pincfg(codec, nid);
4286 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { 4292 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4287 enable_pin_detect(codec, nid, 4293 if (enable_pin_detect(codec, nid,
4288 STAC_INSERT_EVENT); 4294 STAC_INSERT_EVENT))
4289 stac_issue_unsol_event(codec, nid, 4295 stac_issue_unsol_event(codec, nid);
4290 STAC_INSERT_EVENT);
4291 } 4296 }
4292 } 4297 }
4293 } 4298 }
@@ -4332,10 +4337,8 @@ static int stac92xx_init(struct hda_codec *codec)
4332 stac_toggle_power_map(codec, nid, 1); 4337 stac_toggle_power_map(codec, nid, 1);
4333 continue; 4338 continue;
4334 } 4339 }
4335 if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) { 4340 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
4336 enable_pin_detect(codec, nid, STAC_PWR_EVENT); 4341 stac_issue_unsol_event(codec, nid);
4337 stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT);
4338 }
4339 } 4342 }
4340 if (spec->dac_list) 4343 if (spec->dac_list)
4341 stac92xx_power_down(codec); 4344 stac92xx_power_down(codec);
@@ -4598,10 +4601,9 @@ static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4598 } 4601 }
4599} 4602}
4600 4603
4601static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, 4604static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
4602 unsigned char type)
4603{ 4605{
4604 struct sigmatel_event *event = stac_get_event(codec, nid, type); 4606 struct sigmatel_event *event = stac_get_event(codec, nid);
4605 if (!event) 4607 if (!event)
4606 return; 4608 return;
4607 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); 4609 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
@@ -4712,8 +4714,7 @@ static int stac92xx_resume(struct hda_codec *codec)
4712 snd_hda_codec_resume_cache(codec); 4714 snd_hda_codec_resume_cache(codec);
4713 /* fake event to set up pins again to override cached values */ 4715 /* fake event to set up pins again to override cached values */
4714 if (spec->hp_detect) 4716 if (spec->hp_detect)
4715 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], 4717 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
4716 STAC_HP_EVENT);
4717 return 0; 4718 return 0;
4718} 4719}
4719 4720