[alsa-devel] [PATCH RFC 4/7] ALSA: hda - Allow multiple callbacks for jack

Takashi Iwai tiwai at suse.de
Mon Sep 15 10:41:00 CEST 2014


At Thu, 11 Sep 2014 17:01:01 +0200,
David Henningsson wrote:
> 
> 
> 
> On 2014-09-11 16:19, Takashi Iwai wrote:
> > So far, hda_jack infrastructure allows only one callback per jack, and
> > this makes things slightly complicated when a driver wants to assign
> > multiple tasks to a jack, e.g. the standard auto-mute with a power
> > up/down sequence.  This can be simplified if the hda_jack accepts
> > multiple callbacks.
> >
> > This patch is such an extension: the callback-specific part (the
> > function and private_data) is split to another struct from
> > hda_jack_tbl, and multiple such objects can be assigned to a single
> > hda_jack_tbl entry.
> >
> > The new struct hda_jack_callback is passed to each callback function
> > now, thus the patch became bigger than expected.  But these changes
> > are mostly trivial.
> >
> > Signed-off-by: Takashi Iwai <tiwai at suse.de>
> > ---
> >   sound/pci/hda/hda_generic.c    | 19 ++++++++++++-------
> >   sound/pci/hda/hda_generic.h    | 12 ++++++------
> >   sound/pci/hda/hda_jack.c       | 43 +++++++++++++++++++++++++++++-------------
> >   sound/pci/hda/hda_jack.h       | 17 ++++++++++++-----
> >   sound/pci/hda/patch_cirrus.c   |  2 +-
> >   sound/pci/hda/patch_conexant.c |  3 ++-
> >   sound/pci/hda/patch_hdmi.c     | 14 ++++++++++----
> >   sound/pci/hda/patch_realtek.c  | 12 +++++++-----
> >   sound/pci/hda/patch_sigmatel.c | 24 +++++++++++------------
> >   sound/pci/hda/patch_via.c      | 11 +++++++----
> >   10 files changed, 99 insertions(+), 58 deletions(-)
> >
> > diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
> > index 4d605e4ac41c..32a85f9cac4b 100644
> > --- a/sound/pci/hda/hda_generic.c
> > +++ b/sound/pci/hda/hda_generic.c
> > @@ -2032,7 +2032,8 @@ static int create_speaker_out_ctls(struct hda_codec *codec)
> >    * independent HP controls
> >    */
> >
> > -static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack);
> > +static void call_hp_automute(struct hda_codec *codec,
> > +			     struct hda_jack_callback *jack);
> >   static int indep_hp_info(struct snd_kcontrol *kcontrol,
> >   			 struct snd_ctl_elem_info *uinfo)
> >   {
> > @@ -3948,7 +3949,8 @@ static void call_update_outputs(struct hda_codec *codec)
> >   }
> >
> >   /* standard HP-automute helper */
> > -void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
> > +void snd_hda_gen_hp_automute(struct hda_codec *codec,
> > +			     struct hda_jack_callback *jack)
> >   {
> >   	struct hda_gen_spec *spec = codec->spec;
> >   	hda_nid_t *pins = spec->autocfg.hp_pins;
> > @@ -3968,7 +3970,8 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
> >   EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute);
> >
> >   /* standard line-out-automute helper */
> > -void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
> > +void snd_hda_gen_line_automute(struct hda_codec *codec,
> > +			       struct hda_jack_callback *jack)
> >   {
> >   	struct hda_gen_spec *spec = codec->spec;
> >
> > @@ -3988,7 +3991,8 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jac
> >   EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute);
> >
> >   /* standard mic auto-switch helper */
> > -void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *jack)
> > +void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
> > +				struct hda_jack_callback *jack)
> >   {
> >   	struct hda_gen_spec *spec = codec->spec;
> >   	int i;
> > @@ -4011,7 +4015,8 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
> >   EXPORT_SYMBOL_GPL(snd_hda_gen_mic_autoswitch);
> >
> >   /* call appropriate hooks */
> > -static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
> > +static void call_hp_automute(struct hda_codec *codec,
> > +			     struct hda_jack_callback *jack)
> >   {
> >   	struct hda_gen_spec *spec = codec->spec;
> >   	if (spec->hp_automute_hook)
> > @@ -4021,7 +4026,7 @@ static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
> >   }
> >
> >   static void call_line_automute(struct hda_codec *codec,
> > -			       struct hda_jack_tbl *jack)
> > +			       struct hda_jack_callback *jack)
> >   {
> >   	struct hda_gen_spec *spec = codec->spec;
> >   	if (spec->line_automute_hook)
> > @@ -4031,7 +4036,7 @@ static void call_line_automute(struct hda_codec *codec,
> >   }
> >
> >   static void call_mic_autoswitch(struct hda_codec *codec,
> > -				struct hda_jack_tbl *jack)
> > +				struct hda_jack_callback *jack)
> >   {
> >   	struct hda_gen_spec *spec = codec->spec;
> >   	if (spec->mic_autoswitch_hook)
> > diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
> > index 72f5624125fb..61dd5153f512 100644
> > --- a/sound/pci/hda/hda_generic.h
> > +++ b/sound/pci/hda/hda_generic.h
> > @@ -284,11 +284,11 @@ struct hda_gen_spec {
> >
> >   	/* automute / autoswitch hooks */
> >   	void (*hp_automute_hook)(struct hda_codec *codec,
> > -				 struct hda_jack_tbl *tbl);
> > +				 struct hda_jack_callback *cb);
> >   	void (*line_automute_hook)(struct hda_codec *codec,
> > -				   struct hda_jack_tbl *tbl);
> > +				   struct hda_jack_callback *cb);
> >   	void (*mic_autoswitch_hook)(struct hda_codec *codec,
> > -				    struct hda_jack_tbl *tbl);
> > +				    struct hda_jack_callback *cb);
> >   };
> >
> >   int snd_hda_gen_spec_init(struct hda_gen_spec *spec);
> > @@ -320,11 +320,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec);
> >
> >   /* standard jack event callbacks */
> >   void snd_hda_gen_hp_automute(struct hda_codec *codec,
> > -			     struct hda_jack_tbl *jack);
> > +			     struct hda_jack_callback *jack);
> >   void snd_hda_gen_line_automute(struct hda_codec *codec,
> > -			       struct hda_jack_tbl *jack);
> > +			       struct hda_jack_callback *jack);
> >   void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
> > -				struct hda_jack_tbl *jack);
> > +				struct hda_jack_callback *jack);
> >   void snd_hda_gen_update_outputs(struct hda_codec *codec);
> >
> >   #ifdef CONFIG_PM
> > diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
> > index 27fccd2c8d41..13a9e6796379 100644
> > --- a/sound/pci/hda/hda_jack.c
> > +++ b/sound/pci/hda/hda_jack.c
> > @@ -117,8 +117,13 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
> >   		struct hda_jack_tbl *jack = codec->jacktbl.list;
> >   		int i;
> >   		for (i = 0; i < codec->jacktbl.used; i++, jack++) {
> > +			struct hda_jack_callback *cb, *next;
> >   			if (jack->jack)
> >   				snd_device_free(codec->bus->card, jack->jack);
> > +			for (cb = jack->callback; cb; cb = next) {
> > +				next = cb->next;
> > +				kfree(cb);
> > +			}
> >   		}
> >   	}
> >   #endif
> > @@ -215,28 +220,36 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state);
> >   /**
> >    * snd_hda_jack_detect_enable - enable the jack-detection
> >    */
> > -struct hda_jack_tbl *
> > +struct hda_jack_callback *
> >   snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
> > -				    hda_jack_callback cb)
> > +				    hda_jack_callback_fn func)
> >   {
> > -	struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
> > +	struct hda_jack_tbl *jack;
> > +	struct hda_jack_callback *callback = NULL;
> >   	int err;
> >
> > +	jack = snd_hda_jack_tbl_new(codec, nid);
> >   	if (!jack)
> >   		return ERR_PTR(-ENOMEM);
> 
> > -	if (jack->jack_detect)
> > -		return jack; /* already registered */
> 
> This check is an optimisation (do not write unsol verbs to the codec 
> more than once, even if many callbacks are added) and should not be 
> removed. The "if (func) " part should just move above the check.

Right, it makes sense.


Takashi


More information about the Alsa-devel mailing list