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 v2 1/2] ALSA: jack: create jack kcontrols for every jack input device
Date: Fri, 20 Mar 2015 10:27:37 +0100 [thread overview]
Message-ID: <s5hd2446mt2.wl-tiwai@suse.de> (raw)
In-Reply-To: <1426841719-14576-3-git-send-email-yang.jie@intel.com>
At Fri, 20 Mar 2015 16:55:18 +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>
> ---
> include/sound/jack.h | 8 +++++
> sound/core/jack.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 105 insertions(+), 2 deletions(-)
>
> diff --git a/include/sound/jack.h b/include/sound/jack.h
> index 2182350..ef0f0ed 100644
> --- a/include/sound/jack.h
> +++ b/include/sound/jack.h
> @@ -73,6 +73,8 @@ enum snd_jack_types {
>
> struct snd_jack {
> struct input_dev *input_dev;
> + struct list_head kctl_list;
> + struct snd_card *card;
> int registered;
> int type;
> const char *id;
> @@ -82,6 +84,12 @@ struct snd_jack {
> void (*private_free)(struct snd_jack *);
> };
>
> +struct snd_jack_kctl {
> + struct snd_kcontrol *kctl;
> + struct list_head jack_list; /* list of controls belong to the same jack*/
> + unsigned int jack_bit_idx; /* the corresponding jack type bit index */
You can omit jack_ prefix here.
> +};
> +
> #ifdef CONFIG_SND_JACK
Remove CONFIG_SND_JACK, both from Kconfig and ifdefs, as now it's
always enabled together with CONFIG_SND_JACK.
(Or do it later in the patch series.)
> int snd_jack_new(struct snd_card *card, const char *id, int type,
> diff --git a/sound/core/jack.c b/sound/core/jack.c
> index 8658578..741924f 100644
> --- a/sound/core/jack.c
> +++ b/sound/core/jack.c
> @@ -24,6 +24,7 @@
> #include <linux/module.h>
> #include <sound/jack.h>
> #include <sound/core.h>
> +#include <sound/control.h>
>
> static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
> SW_HEADPHONE_INSERT,
> @@ -54,7 +55,13 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
> static int snd_jack_dev_free(struct snd_device *device)
> {
> struct snd_jack *jack = device->device_data;
> + struct snd_card *card = device->card;
> + struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl;
>
> + list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, jack_list) {
> + list_del(&jack_kctl->jack_list);
Use list_del_init(). Otherwise it'll strike back.
(list_del() will be called again in private_free callback from
snd_ctl_remove(), and this can be broken.)
> + snd_ctl_remove(card, jack_kctl->kctl);
> + }
> if (jack->private_free)
> jack->private_free(jack);
>
> @@ -100,6 +107,73 @@ static int snd_jack_dev_register(struct snd_device *device)
> return err;
> }
>
> +
> +/* get the first unused/available index number for the given kctl name */
> +static int get_available_index(struct snd_card *card, const char *name)
> +{
> + struct snd_kcontrol *kctl;
> + int idx = 0;
> + int len = strlen(name);
> +
> + down_write(&card->controls_rwsem);
Use down_read(), as Liam already suggested.
> + next:
> + list_for_each_entry(kctl, &card->controls, list) {
> + if (!strncmp(name, kctl->id.name, len) &&
> + !strcmp(" Jack", kctl->id.name + len) &&
> + kctl->id.index == idx) {
> + idx++;
> + goto next;
> + }
> + }
Better to split a small function, e.g.
while (!jack_ctl_name_found(card, kctl))
idx++;
than using ugly goto.
> + up_write(&card->controls_rwsem);
> + return idx;
> +}
> +
> +static void kctl_private_free(struct snd_kcontrol *kctl)
> +{
> + struct snd_jack_kctl *jack_kctl = kctl->private_data;
> + list_del(&jack_kctl->jack_list);
kfree() is forgotten.
> +}
> +
> +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;
> + if (type & testbit) {
With this implementation, you'll get multiple boolean kctls for a
headset. I thought we agreed with creating a single boolean for
headset?
In the case of input device, the situation is a bit different, so we
shouldn't mix up.
> + index = get_available_index(card,jack->id);
> + kctl = snd_kctl_jack_new(jack->id, index, card);
> + if (!kctl)
> + return -ENOMEM;
> +
> + err = snd_ctl_add(card, kctl);
> + if (err < 0)
> + return err;
> +
> + jack_kctl = kzalloc(sizeof(*jack_kctl), GFP_KERNEL);
Missing NULL check.
> + jack_kctl->kctl = kctl;
> +
> + kctl->private_data = jack_kctl;
> + kctl->private_free = kctl_private_free;
> +
> + /* use jack_bit_idx for the kctl type bit */
> + jack_kctl->jack_bit_idx = i;
This can be better to hold bit mask instead of bit index.
Then in the below...
> @@ -245,13 +327,26 @@ void snd_jack_report(struct snd_jack *jack, int status)
....
> }
>
> input_sync(jack->input_dev);
> +
> + for (i = 0; i < fls(SND_JACK_BTN_0); i++) {
> + int testbit = 1 << i;
> + if (jack->type & testbit) {
> + list_for_each_entry(jack_kctl, &jack->kctl_list, jack_list) {
> + if (jack_kctl->jack_bit_idx == i) {
> + snd_kctl_jack_report(jack->card, jack_kctl->kctl,
> + status & testbit);
> + }
.... you can reduce to a single loop.
thanks,
Takashi
next prev parent reply other threads:[~2015-03-20 9:27 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-20 8:55 [PATCH v2 0/2] ALSA: jack: Refactoring for jack kctls Jie Yang
2015-03-20 8:55 ` Jie Yang
2015-03-20 8:55 ` [PATCH v2 1/2] ALSA: jack: create jack kcontrols for every jack input device Jie Yang
2015-03-20 9:27 ` Takashi Iwai [this message]
2015-03-20 9:29 ` Takashi Iwai
2015-03-20 12:22 ` Jie, Yang
2015-03-20 12:26 ` Takashi Iwai
2015-03-20 12:50 ` Jie, Yang
2015-03-20 13:21 ` Takashi Iwai
2015-03-20 13:49 ` Jie, Yang
2015-03-20 14:18 ` Takashi Iwai
2015-03-23 10:56 ` Tanu Kaskinen
2015-03-23 11:51 ` David Henningsson
2015-03-23 11:59 ` Takashi Iwai
2015-03-23 16:41 ` Mark Brown
2015-03-24 6:50 ` David Henningsson
2015-03-24 17:57 ` Mark Brown
2015-03-25 0:48 ` Raymond Yau
2015-03-25 2:14 ` Raymond Yau
2015-03-25 13:53 ` Jie, Yang
2015-03-25 16:13 ` Raymond Yau
2015-03-26 6:42 ` David Henningsson
2015-03-26 8:29 ` Jie, Yang
2015-03-26 9:05 ` David Henningsson
2015-03-26 12:39 ` Jie, Yang
2015-03-27 0:39 ` Raymond Yau
2015-03-27 2:13 ` Jie, Yang
2015-03-26 12:43 ` Jie, Yang
2015-03-27 6:50 ` David Henningsson
2015-03-27 7:45 ` Jie, Yang
2015-03-27 8:01 ` David Henningsson
2015-03-27 9:11 ` Jie, Yang
2015-03-30 7:27 ` David Henningsson
2015-03-26 2:34 ` Raymond Yau
2015-03-25 7:53 ` Jie, Yang
2015-03-25 9:27 ` Tanu Kaskinen
2015-03-25 14:13 ` Jie, Yang
2015-03-28 6:09 ` Raymond Yau
2015-03-20 10:30 ` Raymond Yau
2015-03-20 8:55 ` [PATCH v2 2/2] ALSA: hda - Remove jack kctls Jie Yang
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=s5hd2446mt2.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