Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Jie Yang <yang.jie@intel.com>
Cc: Liam Girdwood <liam.r.girdwood@linux.intel.com>,
	alsa-devel@alsa-project.org, broonie@kernel.org,
	liam.r.girdwood@intel.com
Subject: Re: [PATCH v3 1/2] ALSA: jack: create jack kcontrols for every jack input device
Date: Fri, 20 Mar 2015 17:17:26 +0100	[thread overview]
Message-ID: <s5ha8z7zlrd.wl-tiwai@suse.de> (raw)
In-Reply-To: <1426865953-1606-2-git-send-email-yang.jie@intel.com>

At Fri, 20 Mar 2015 23:39:12 +0800,
Jie Yang wrote:
> 
> Currently the ALSA jack core registers only input devices for each jack
> registered. These jack input devices are not readable by userspace devices
> that run as non root.
> 
> This patch adds support for additionally registering jack kcontrol devices
> for every input jack registered. This allows non root userspace to read
> jack status.
> 
> Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
> Modified-by: Jie Yang <yang.jie@intel.com>
> Signed-off-by: Jie Yang <yang.jie@intel.com>
> Reveiwed-by: Mark Brown <broonie@kernel.org>

Thanks for a quick update.  It's getting better, but still some points
to be fixed.  Let's see...


> +struct snd_jack_kctl {
> +	struct snd_kcontrol *kctl;
> +	struct list_head jack_list;		/* list of controls belong to the same jack*/

jack_ prefix is superfluous.

> +static int jack_ctl_name_found(struct snd_card *card, const char *name, int index)

Use bool.

> +{
> +	struct snd_kcontrol *kctl;
> +	int len = strlen(name);
> +
> +	down_read(&card->controls_rwsem);
> +
> +	list_for_each_entry(kctl, &card->controls, list) {
> +		if (!strncmp(name, kctl->id.name, len) &&
> +		    !strcmp(" Jack", kctl->id.name + len) &&
> +		    kctl->id.index == index) {

This doesn't work when ctl elements are with multiple counts.  A
single kctl object may contain multiple snd_kcontrol_volatile entries.
That's why snd_ctl_find_id() checks like:

	list_for_each_entry(kctl, &card->controls, list) {
		....
		if (kctl->id.index > id->index)
			continue;
		if (kctl->id.index + kctl->count <= id->index)
			continue;

Also, more importantly, your code checks only the name string.  But
the same name string can be assigned for different iface, device and
subdevice entries.  You need to compare them as well.

That said, it'd be even simpler just to call snd_ctl_find_id() after
creating a ctl id instance instead of writing an own funciton.  It
ends up with a bit more stack usage, but it should be still
acceptable.


> +static int snd_jack_new_kctl(struct snd_card *card, struct snd_jack *jack, int type)
> +{
> +	struct snd_kcontrol *kctl;
> +	struct snd_jack_kctl *jack_kctl;
> +	int i, err, index, state = 0 /* use 0 for default state ?? */;
> +
> +	INIT_LIST_HEAD(&jack->kctl_list);
> +	for (i = 0; i < fls(SND_JACK_BTN_0); i++) {
> +		int testbit = 1 << i;
> +
> +		/* we only new headphone kctl for headset jack */
> +		if ((testbit == SND_JACK_MICROPHONE) &&
> +				((type & SND_JACK_HEADSET) == SND_JACK_HEADSET))
> +			continue;

The parentheses are superfluous.

> +		/* we only new lineout kctl for avout jack */
> +		if ((testbit == SND_JACK_VIDEOOUT) &&
> +				((type & SND_JACK_AVOUT) == SND_JACK_AVOUT))
> +			continue;
> +
> +		if (type & testbit) {

This check can be at the beginning of the loop, i.e.

		if (!(type & testbit))
			continue;

then you'll reduce one indent level.


Now, a bigger question:

> +			index = get_available_index(card,jack->id);
> +			kctl = snd_kctl_jack_new(jack->id, index, card);

So, here you are creating multiple kctl elements with the very same
name string.  Did you take a look at the actual usages of
snd_jack_new(), especially snd_soc_card_jack_new()?

Try like

% git grep -A2 snd_soc_card_jack_new sound/soc/

sound/soc/fsl/imx-es8328.c:             ret = snd_soc_card_jack_new(rtd->card, "Headphone",
sound/soc/fsl/imx-es8328.c-                                         SND_JACK_HEADPHONE | SND_JACK_BTN_0,
sound/soc/fsl/imx-es8328.c-                                         &headset_jack, NULL, 0);
--
sound/soc/fsl/wm1133-ev1.c:     snd_soc_card_jack_new(rtd->card, "Headphone", SND_JACK_HEADPHONE,
sound/soc/fsl/wm1133-ev1.c-                           &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins));
sound/soc/fsl/wm1133-ev1.c-     wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
--
sound/soc/fsl/wm1133-ev1.c:     snd_soc_card_jack_new(rtd->card, "Microphone",
sound/soc/fsl/wm1133-ev1.c-                           SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack,
sound/soc/fsl/wm1133-ev1.c-                           mic_jack_pins, ARRAY_SIZE(mic_jack_pins));
.....

As you'll find through the whole output, many calls are combined with
SND_JACK_BTN_* bits.  And think again how this will result with your
patch.  A call like

	snd_soc_card_jack_new(card, "Headphone",
		SND_JACK_HEADPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1, ...)

would give three kctls, all "Headphone Jack" with indices 0, 1 and 2.
How user-space knows what is for what?

Also, when you look through the grep above, you'll find that many
calls already contain "Jack" name suffix.  So, they will result in
a name like "Headset Jack Jack".

One last bit:
> +			/* set initial jack state */
> +			snd_kctl_jack_report(card, kctl, state & testbit);

This can be dropped.  The value is zero as default, so unless the
actual value is different, you don't need to call it. 

Or, yet another last bit: remove EXPORT_SYMBOL_GPL() from ctljack.c,
as they are merely internal functions.  But this can be done another
patch later.


Takashi

  reply	other threads:[~2015-03-20 16:17 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-20 15:39 [PATCH v3 0/2] ALSA: jack: Refactoring for jack kctls Jie Yang
2015-03-20 15:39 ` [PATCH v3 1/2] ALSA: jack: create jack kcontrols for every jack input device Jie Yang
2015-03-20 16:17   ` Takashi Iwai [this message]
2015-03-21  2:22     ` Jie, Yang
2015-03-21  7:46       ` Takashi Iwai
2015-03-23 10:08       ` Tanu Kaskinen
2015-03-23 11:57         ` Takashi Iwai
2015-03-23 14:57           ` Mark Brown
2015-03-25  4:11           ` Jie, Yang
2015-03-25  5:27             ` Raymond Yau
2015-03-25  6:13             ` Takashi Iwai
2015-03-20 15:39 ` [PATCH v3 2/2] ALSA: hda - Remove jack kctls Jie Yang
2015-03-20 16:21   ` Takashi Iwai
2015-03-21  0:23     ` Jie, Yang
2015-03-23  9:18 ` [PATCH v3 0/2] ALSA: jack: Refactoring for " David Henningsson
2015-03-23 15:00   ` Mark Brown
2015-03-23 15:09     ` Takashi Iwai
2015-03-23 16:35       ` Mark Brown
2015-03-23 16:38         ` Takashi Iwai
2015-03-23 16:52           ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=s5ha8z7zlrd.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=liam.r.girdwood@intel.com \
    --cc=liam.r.girdwood@linux.intel.com \
    --cc=yang.jie@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox