diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 5fe34a8d8c81..e4581a42ace5 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -42,7 +42,7 @@ static void snd_hda_generate_beep(struct work_struct *work) return; /* generate tone */ - snd_hda_codec_write_cache(codec, beep->nid, 0, + snd_hda_codec_write(codec, beep->nid, 0, AC_VERB_SET_BEEP_CONTROL, beep->tone); } @@ -119,7 +119,7 @@ static void snd_hda_do_detach(struct hda_beep *beep) beep->dev = NULL; cancel_work_sync(&beep->beep_work); /* turn off beep for sure */ - snd_hda_codec_write_cache(beep->codec, beep->nid, 0, + snd_hda_codec_write(beep->codec, beep->nid, 0, AC_VERB_SET_BEEP_CONTROL, 0); } @@ -192,7 +192,7 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) beep->enabled = enable; if (!enable) { /* turn off beep */ - snd_hda_codec_write_cache(beep->codec, beep->nid, 0, + snd_hda_codec_write(beep->codec, beep->nid, 0, AC_VERB_SET_BEEP_CONTROL, 0); } if (beep->mode == HDA_BEEP_MODE_SWREG) { @@ -239,8 +239,12 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) mutex_init(&beep->mutex); if (beep->mode == HDA_BEEP_MODE_ON) { - beep->enabled = 1; - snd_hda_do_register(&beep->register_work); + int err = snd_hda_do_attach(beep); + if (err < 0) { + kfree(beep); + codec->beep = NULL; + return err; + } } return 0; @@ -253,7 +257,7 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) if (beep) { cancel_work_sync(&beep->register_work); cancel_delayed_work(&beep->unregister_work); - if (beep->enabled) + if (beep->dev) snd_hda_do_detach(beep); codec->beep = NULL; kfree(beep); diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 950ee5cfcacf..f98b47cd6cfb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1327,11 +1327,13 @@ EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); */ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) { - u32 pincap = snd_hda_query_pin_caps(codec, nid); - - if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ - snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); + u32 pincap; + if (!codec->no_trigger_sense) { + pincap = snd_hda_query_pin_caps(codec, nid); + if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ + snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); + } return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0); } diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 1d541b7f5547..0a770a28e71f 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -817,6 +817,7 @@ struct hda_codec { unsigned int pin_amp_workaround:1; /* pin out-amp takes index * (e.g. Conexant codecs) */ + unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ unsigned int power_transition :1; /* power-state in transition */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ff8ad46cc50e..ec9c348336cc 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -356,6 +356,7 @@ struct azx_dev { */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ + int device; /* last device number assigned to */ unsigned int opened :1; unsigned int running :1; @@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure(struct azx *chip) */ /* assign a stream for the PCM */ -static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) +static inline struct azx_dev * +azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) { int dev, i, nums; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + struct azx_dev *res = NULL; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dev = chip->playback_index_offset; nums = chip->playback_streams; } else { @@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) } for (i = 0; i < nums; i++, dev++) if (!chip->azx_dev[dev].opened) { - chip->azx_dev[dev].opened = 1; - return &chip->azx_dev[dev]; + res = &chip->azx_dev[dev]; + if (res->device == substream->pcm->device) + break; } - return NULL; + if (res) { + res->opened = 1; + res->device = substream->pcm->device; + } + return res; } /* release the assigned stream */ @@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) int err; mutex_lock(&chip->open_mutex); - azx_dev = azx_assign_device(chip, substream->stream); + azx_dev = azx_assign_device(chip, substream); if (azx_dev == NULL) { mutex_unlock(&chip->open_mutex); return -EBUSY; diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 1a36137e13ec..69a941c7b158 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1186,6 +1186,8 @@ static int patch_ad1986a(struct hda_codec *codec) */ spec->multiout.no_share_stream = 1; + codec->no_trigger_sense = 1; + return 0; } @@ -1371,6 +1373,8 @@ static int patch_ad1983(struct hda_codec *codec) codec->patch_ops = ad198x_patch_ops; + codec->no_trigger_sense = 1; + return 0; } @@ -1813,6 +1817,9 @@ static int patch_ad1981(struct hda_codec *codec) codec->patch_ops.unsol_event = ad1981_hp_unsol_event; break; } + + codec->no_trigger_sense = 1; + return 0; } @@ -3118,6 +3125,8 @@ static int patch_ad1988(struct hda_codec *codec) #endif spec->vmaster_nid = 0x04; + codec->no_trigger_sense = 1; + return 0; } @@ -3330,6 +3339,8 @@ static int patch_ad1884(struct hda_codec *codec) codec->patch_ops = ad198x_patch_ops; + codec->no_trigger_sense = 1; + return 0; } @@ -4287,6 +4298,8 @@ static int patch_ad1884a(struct hda_codec *codec) break; } + codec->no_trigger_sense = 1; + return 0; } @@ -4623,6 +4636,9 @@ static int patch_ad1882(struct hda_codec *codec) spec->mixers[2] = ad1882_6stack_mixers; break; } + + codec->no_trigger_sense = 1; + return 0; } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index eeda7beeb57a..2291a8396817 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4453,14 +4453,7 @@ static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) { if (!nid) return 0; - /* NOTE: we can't use snd_hda_jack_detect() here because STAC/IDT - * codecs behave wrongly when SET_PIN_SENSE is triggered, although - * the pincap gives TRIG_REQ bit. - */ - if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0) & - AC_PINSENSE_PRESENCE) - return 1; - return 0; + return snd_hda_jack_detect(codec, nid); } static void stac92xx_line_out_detect(struct hda_codec *codec, @@ -4962,6 +4955,7 @@ static int patch_stac9200(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); spec->pin_nids = stac9200_pin_nids; @@ -5024,6 +5018,7 @@ static int patch_stac925x(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); spec->pin_nids = stac925x_pin_nids; @@ -5108,6 +5103,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); @@ -5255,6 +5251,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; spec->digbeep_nid = 0x21; @@ -5418,6 +5415,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; codec->patch_ops = stac92xx_patch_ops; spec->num_pins = STAC92HD71BXX_NUM_PINS; @@ -5661,6 +5659,7 @@ static int patch_stac922x(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); spec->pin_nids = stac922x_pin_nids; @@ -5764,6 +5763,7 @@ static int patch_stac927x(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; codec->slave_dig_outs = stac927x_slave_dig_outs; spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); @@ -5898,6 +5898,7 @@ static int patch_stac9205(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); spec->pin_nids = stac9205_pin_nids; @@ -6053,6 +6054,7 @@ static int patch_stac9872(struct hda_codec *codec) spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); spec->pin_nids = stac9872_pin_nids;