* [RFC PATCH 1/11] expose sound device topology information
@ 2012-08-27 22:28 Clemens Ladisch
2012-08-27 22:29 ` [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO Clemens Ladisch
` (11 more replies)
0 siblings, 12 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:28 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Hi,
these are some tentative patches to allow sound drivers to provide
routing information to userspace. (So far, snd-usb-audio has a partial
implementation; I haven't yet had time for snd-hda-intel. I haven't
even looked at ASoC.)
The media controller API <linux/media.h> allows prividing routing
information, but its implementation does not quite fit the sound
drivers:
* it allows reconfiguration of links, but not in a way that would be
useful for ALSA selector controls;
* it allows drivers to access the entity graph and pipelines, which is
not needed;
* it is rather heavyweight.
Therefore, these patches create their own implementation of the media
controller API. In this implementation, all entity and link information
is completely static, and more space-efficient.
For simplicity, the ioctls hook into the ALSA control device instead
of creating a new /dev/media* device.
The separate implementation does not allow sharing of one media
controller device in the case of combined audio/video devices. However,
separate drivers would already be a problem for HDMI outputs (GPU and
sound); it appears we might need some mechanism to connect the
topologies of multiple media devices.
TLVs (for jack entities, and for associating controls with entities)
are not yet defined.
Example output for my simple UA-1A device (not all information is
decoded correctly):
$ media-ctl -p -d /dev/snd/controlC5
Opening media device /dev/snd/controlC5
Enumerating entities
Found 4 entities
Enumerating pads and links
Media controller API version 0.0.0
Media device information
------------------------
driver snd-usb-audio
model EDIROL UA-1A
serial
bus info usb-0000:00:12.2-4.3
hw revision 0x101
driver version 0.0.0
Device topology
- entity 1: USB Audio (1 pad, 1 link)
type Node subtype ALSA
device node name /dev/tty (should be hw:5,0,0)
pad0: Source
-> "OT3":0 [ENABLED,IMMUTABLE]
- entity 3: OT3 (1 pad, 1 link)
type Unknown subtype Unknown (should be Jack)
pad0: Sink
<- "USB Audio":0 [ENABLED,IMMUTABLE]
- entity 4: IT4 (1 pad, 1 link)
type Unknown subtype Unknown
pad0: Source
-> "USB Audio":0 [ENABLED,IMMUTABLE]
- entity 7: USB Audio (1 pad, 1 link)
type Node subtype ALSA
device node name /dev/tty
pad0: Sink
<- "IT4":0 [ENABLED,IMMUTABLE]
include/linux/media.h | 9
include/sound/core.h | 13 +
include/sound/media.h | 116 ++++++++++
include/sound/pcm.h | 6
sound/core/Kconfig | 7
sound/core/Makefile | 1
sound/core/init.c | 4
sound/core/media.c | 425 ++++++++++++++++++++++++++++++++++++++
sound/core/pcm.c | 46 ++++
sound/core/sound.c | 3
sound/pci/hda/hda_intel.c | 2
sound/usb/card.c | 2
sound/usb/mixer.c | 278 ++++++++++++++++++++++++
sound/usb/quirks.c | 4
sound/usb/stream.c | 16 -
sound/usb/stream.h | 1
16 files changed, 925 insertions(+), 8 deletions(-)
Regards,
Clemens
^ permalink raw reply [flat|nested] 17+ messages in thread
* [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
@ 2012-08-27 22:29 ` Clemens Ladisch
2012-09-07 2:13 ` Mark Brown
2012-08-27 22:30 ` [RFC PATCH 02/11] ALSA: implement MEDIA_IOC_ENUM_ENTITIES Clemens Ladisch
` (10 subsequent siblings)
11 siblings, 1 reply; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:29 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Add a callback to snd_card to allow card drivers to return driver-
specific information.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
include/sound/core.h | 5 +++
include/sound/media.h | 50 ++++++++++++++++++++++++++++++++
sound/core/Kconfig | 7 +++++
sound/core/Makefile | 1 +
sound/core/media.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++
sound/core/sound.c | 3 ++
6 files changed, 142 insertions(+), 0 deletions(-)
create mode 100644 include/sound/media.h
create mode 100644 sound/core/media.c
diff --git a/include/sound/core.h b/include/sound/core.h
index bc05668..5eca6f5 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -42,6 +42,7 @@ struct pci_dev;
struct module;
struct device;
struct device_attribute;
+struct snd_media_card_ops;
/* device allocation stuff */
@@ -145,6 +146,10 @@ struct snd_card {
struct snd_mixer_oss *mixer_oss;
int mixer_oss_change_count;
#endif
+
+#ifdef CONFIG_SND_MEDIA
+ const struct snd_media_card_ops *media_ops;
+#endif
};
#ifdef CONFIG_PM
diff --git a/include/sound/media.h b/include/sound/media.h
new file mode 100644
index 0000000..d196219
--- /dev/null
+++ b/include/sound/media.h
@@ -0,0 +1,50 @@
+/*
+ * media controller interface for ALSA driver
+ * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SOUND_MEDIA_H_INCLUDED
+#define SOUND_MEDIA_H_INCLUDED
+
+#include <linux/init.h>
+
+struct snd_card;
+struct media_device_info;
+
+struct snd_media_card_ops {
+ int (*get_info)(struct snd_card *card, struct media_device_info *info);
+};
+
+#ifdef CONFIG_SND_MEDIA
+
+#define snd_card_set_media_ops(card, ops) ((card)->media_ops = (ops))
+
+void __init snd_media_init(void);
+void __exit snd_media_exit(void);
+
+#else /* CONFIG_SND_MEDIA */
+
+#define snd_card_set_media_ops(card, ops)
+
+static inline void snd_media_init()
+{ }
+static inline void snd_media_exit()
+{ }
+
+#endif /* !CONFIG_SND_MEDIA */
+
+#endif
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index b413ed0..fadbdf5 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -147,6 +147,13 @@ config SND_SEQ_RTCTIMER_DEFAULT
If in doubt, say Y.
+config SND_MEDIA
+ bool "Media Controller API (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ Say Y here to enable the media controller API, which allows to
+ retrieve the internal topology of sound devices.
+
config SND_DYNAMIC_MINORS
bool "Dynamic device file minor numbers"
help
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 43d4117..b6de542 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -9,6 +9,7 @@ snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
snd-$(CONFIG_SND_VMASTER) += vmaster.o
snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o
snd-$(CONFIG_SND_JACK) += jack.o
+snd-$(CONFIG_SND_MEDIA) += media.o
snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
pcm_memory.o
diff --git a/sound/core/media.c b/sound/core/media.c
new file mode 100644
index 0000000..6ceb12a
--- /dev/null
+++ b/sound/core/media.c
@@ -0,0 +1,76 @@
+/*
+ * media controller interface for ALSA driver
+ * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/media.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/media.h>
+
+static int snd_media_device_info(struct snd_card *card,
+ struct media_device_info __user *infop)
+{
+ struct media_device_info info;
+ int err;
+
+ memset(&info, 0, sizeof(info));
+
+ if (card->dev && card->dev->driver)
+ strlcpy(info.driver, card->dev->driver->name, sizeof(info.driver));
+ strlcpy(info.model, card->shortname, sizeof(info.model));
+ info.media_version = MEDIA_API_VERSION;
+
+ if (card->media_ops) {
+ err = card->media_ops->get_info(card, &info);
+ if (err < 0)
+ return err;
+ }
+
+ return copy_to_user(infop, &info, sizeof(info));
+}
+
+static int snd_media_control_ioctl(struct snd_card *card,
+ struct snd_ctl_file *ctl_file,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+
+ switch (cmd) {
+ case MEDIA_IOC_DEVICE_INFO:
+ return snd_media_device_info(card, argp);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+void __init snd_media_init(void)
+{
+ snd_ctl_register_ioctl(snd_media_control_ioctl);
+ snd_ctl_register_ioctl_compat(snd_media_control_ioctl);
+}
+
+void __exit snd_media_exit(void)
+{
+ snd_ctl_unregister_ioctl(snd_media_control_ioctl);
+ snd_ctl_unregister_ioctl_compat(snd_media_control_ioctl);
+}
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 28f3559..7a7721c 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -30,6 +30,7 @@
#include <sound/version.h>
#include <sound/control.h>
#include <sound/initval.h>
+#include <sound/media.h>
#include <linux/kmod.h>
#include <linux/mutex.h>
@@ -467,6 +468,7 @@ static int __init alsa_sound_init(void)
return -ENOMEM;
}
snd_info_minor_register();
+ snd_media_init();
#ifndef MODULE
printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
#endif
@@ -475,6 +477,7 @@ static int __init alsa_sound_init(void)
static void __exit alsa_sound_exit(void)
{
+ snd_media_exit();
snd_info_minor_unregister();
snd_info_done();
unregister_chrdev(major, "alsa");
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 02/11] ALSA: implement MEDIA_IOC_ENUM_ENTITIES
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
2012-08-27 22:29 ` [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO Clemens Ladisch
@ 2012-08-27 22:30 ` Clemens Ladisch
2012-08-27 22:30 ` [RFC PATCH 03/11] ALSA: pcm: add ALSA PCM device entities Clemens Ladisch
` (9 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:30 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Allow drivers to create entities. To avoid bloat, the snd_media_entity
structure stores only basic information and retrieves the full entitiy
information on demand with a callback.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
include/sound/core.h | 5 ++
include/sound/media.h | 23 ++++++++++
sound/core/init.c | 4 ++
sound/core/media.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 145 insertions(+), 1 deletions(-)
diff --git a/include/sound/core.h b/include/sound/core.h
index 5eca6f5..072b642 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -51,7 +51,8 @@ struct snd_media_card_ops;
typedef int __bitwise snd_device_type_t;
#define SNDRV_DEV_TOPLEVEL ((__force snd_device_type_t) 0)
#define SNDRV_DEV_CONTROL ((__force snd_device_type_t) 1)
-#define SNDRV_DEV_LOWLEVEL_PRE ((__force snd_device_type_t) 2)
+#define SNDRV_DEV_MEDIA ((__force snd_device_type_t) 2)
+#define SNDRV_DEV_LOWLEVEL_PRE ((__force snd_device_type_t) 3)
#define SNDRV_DEV_LOWLEVEL_NORMAL ((__force snd_device_type_t) 0x1000)
#define SNDRV_DEV_PCM ((__force snd_device_type_t) 0x1001)
#define SNDRV_DEV_RAWMIDI ((__force snd_device_type_t) 0x1002)
@@ -149,6 +150,8 @@ struct snd_card {
#ifdef CONFIG_SND_MEDIA
const struct snd_media_card_ops *media_ops;
+ struct mutex media_mutex;
+ struct list_head media_entities;
#endif
};
diff --git a/include/sound/media.h b/include/sound/media.h
index d196219..65dd068 100644
--- a/include/sound/media.h
+++ b/include/sound/media.h
@@ -23,16 +23,29 @@
#include <linux/init.h>
struct snd_card;
+struct snd_media_entity;
struct media_device_info;
+struct media_entity_desc;
struct snd_media_card_ops {
int (*get_info)(struct snd_card *card, struct media_device_info *info);
};
+typedef int (*snd_media_entity_get_desc_t)(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc);
+
#ifdef CONFIG_SND_MEDIA
#define snd_card_set_media_ops(card, ops) ((card)->media_ops = (ops))
+int snd_media_entity_create(struct snd_card *card,
+ snd_media_entity_get_desc_t get_desc,
+ unsigned int id,
+ unsigned int sinks, unsigned int sources,
+ void *private_data);
+
+int snd_media_create(struct snd_card *card);
void __init snd_media_init(void);
void __exit snd_media_exit(void);
@@ -40,6 +53,16 @@ void __exit snd_media_exit(void);
#define snd_card_set_media_ops(card, ops)
+static inline int snd_media_entity_create(struct snd_card *card,
+ snd_media_entity_get_desc_t get_desc,
+ unsigned int id,
+ unsigned int sinks, unsigned int sources,
+ void *private_data)
+{ return 0; }
+
+
+static inline int snd_media_create(struct snd_card *card)
+{ return 0; }
static inline void snd_media_init()
{ }
static inline void snd_media_exit()
diff --git a/sound/core/init.c b/sound/core/init.c
index d8ec849..e16ef16 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -32,6 +32,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/info.h>
+#include <sound/media.h>
/* monitor files for graceful shutdown (hotplug) */
struct snd_monitor_file {
@@ -224,6 +225,9 @@ int snd_card_create(int idx, const char *xid,
snd_printk(KERN_ERR "unable to register control minors\n");
goto __error;
}
+ err = snd_media_create(card);
+ if (err < 0)
+ goto __error_ctl;
err = snd_info_card_create(card);
if (err < 0) {
snd_printk(KERN_ERR "unable to create card info\n");
diff --git a/sound/core/media.c b/sound/core/media.c
index 6ceb12a..aa94175 100644
--- a/sound/core/media.c
+++ b/sound/core/media.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/list.h>
#include <linux/media.h>
#include <linux/string.h>
#include <linux/uaccess.h>
@@ -27,6 +28,87 @@
#include <sound/control.h>
#include <sound/media.h>
+struct snd_media_entity {
+ struct list_head list;
+ snd_media_entity_get_desc_t get_desc;
+ void *private_data;
+ unsigned int id;
+ unsigned int sinks, sources;
+};
+
+static struct snd_media_entity *search_entity(struct snd_card *card,
+ unsigned int id)
+{
+ struct snd_media_entity *e;
+ bool next = id & MEDIA_ENT_ID_FLAG_NEXT;
+
+ id &= ~MEDIA_ENT_ID_FLAG_NEXT;
+ if (next)
+ id++;
+
+ list_for_each_entry(e, &card->media_entities, list)
+ if (e->id >= id)
+ return next || e->id == id ? e : NULL;
+
+ return NULL;
+}
+
+int snd_media_entity_create(struct snd_card *card,
+ snd_media_entity_get_desc_t get_desc,
+ unsigned int id,
+ unsigned int sinks, unsigned int sources,
+ void *private_data)
+{
+ struct snd_media_entity *entity;
+ struct list_head *pos;
+
+ entity = kzalloc(sizeof(*entity), GFP_KERNEL);
+ if (!entity)
+ return -ENOMEM;
+ entity->get_desc = get_desc;
+ entity->id = id;
+ entity->sinks = sinks;
+ entity->sources = sources;
+ entity->private_data = private_data;
+
+ mutex_lock(&card->media_mutex);
+ list_for_each_prev(pos, &card->media_entities)
+ if (list_entry(pos, struct snd_media_entity, list)->id < id)
+ break;
+ list_add(&entity->list, pos);
+ mutex_unlock(&card->media_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(snd_media_entity_create);
+
+static int snd_media_dev_free(struct snd_device *device)
+{
+ struct snd_card *card = device->device_data;
+ struct snd_media_entity *e;
+
+ while (!list_empty(&card->media_entities)) {
+ e = list_first_entry(&card->media_entities,
+ struct snd_media_entity, list);
+ list_del(&e->list);
+ kfree(e);
+ }
+
+ return 0;
+}
+
+int snd_media_create(struct snd_card *card)
+{
+ static struct snd_device_ops ops = {
+ .dev_free = snd_media_dev_free,
+ };
+
+ mutex_init(&card->media_mutex);
+ INIT_LIST_HEAD(&card->media_entities);
+
+ return snd_device_new(card, SNDRV_DEV_MEDIA, card, &ops);
+}
+
static int snd_media_device_info(struct snd_card *card,
struct media_device_info __user *infop)
{
@@ -49,6 +131,36 @@ static int snd_media_device_info(struct snd_card *card,
return copy_to_user(infop, &info, sizeof(info));
}
+static int snd_media_enum_entities(struct snd_card *card,
+ struct media_entity_desc __user *descp)
+{
+ struct media_entity_desc desc;
+ struct snd_media_entity *entity;
+ int err;
+
+ if (copy_from_user(&desc, descp, sizeof(desc)))
+ return -EFAULT;
+
+ mutex_lock(&card->media_mutex);
+ entity = search_entity(card, desc.id);
+ mutex_unlock(&card->media_mutex);
+ if (!entity)
+ return -EINVAL;
+
+ desc.id = entity->id;
+ desc.revision = 0;
+ desc.flags = 0;
+ desc.group_id = 0;
+ desc.pads = entity->sinks + entity->sources;
+ desc.links = 0;
+
+ err = entity->get_desc(card, entity->private_data, &desc);
+ if (err < 0)
+ return err;
+
+ return copy_to_user(descp, &desc, sizeof(desc));
+}
+
static int snd_media_control_ioctl(struct snd_card *card,
struct snd_ctl_file *ctl_file,
unsigned int cmd, unsigned long arg)
@@ -58,6 +170,8 @@ static int snd_media_control_ioctl(struct snd_card *card,
switch (cmd) {
case MEDIA_IOC_DEVICE_INFO:
return snd_media_device_info(card, argp);
+ case MEDIA_IOC_ENUM_ENTITIES:
+ return snd_media_enum_entities(card, argp);
default:
return -ENOIOCTLCMD;
}
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 03/11] ALSA: pcm: add ALSA PCM device entities
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
2012-08-27 22:29 ` [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO Clemens Ladisch
2012-08-27 22:30 ` [RFC PATCH 02/11] ALSA: implement MEDIA_IOC_ENUM_ENTITIES Clemens Ladisch
@ 2012-08-27 22:30 ` Clemens Ladisch
2012-08-27 22:31 ` [RFC PATCH 04/11] ALSA: implement MEDIA_IOC_ENUM_LINKS (1) Clemens Ladisch
` (8 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:30 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Add a helper function for creating entities representing ALSA PCM
devices.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
include/sound/pcm.h | 6 ++++++
sound/core/pcm.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 39e26a3..f0a80b7 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -480,6 +480,12 @@ int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count,
struct snd_pcm **rpcm);
int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count);
+#ifdef CONFIG_SND_MEDIA
+int snd_pcm_media_entities_create(struct snd_pcm *pcm, int stream,
+ unsigned int id);
+#else
+#define snd_pcm_media_entities_create(pcm, stream, id)
+#endif
int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 1a3070b..a138c57 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -25,11 +25,13 @@
#include <linux/time.h>
#include <linux/mutex.h>
#include <linux/device.h>
+#include <linux/media.h>
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/pcm.h>
#include <sound/control.h>
#include <sound/info.h>
+#include <sound/media.h>
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");
@@ -1136,6 +1138,50 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
EXPORT_SYMBOL(snd_pcm_notify);
+#ifdef CONFIG_SND_MEDIA
+static int snd_pcm_get_entity_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ struct snd_pcm_substream *substream = private_data;
+
+ if (memcmp(substream->name, "subdevice #", 11))
+ strlcpy(desc->name, substream->name, sizeof(desc->name));
+ else
+ strlcpy(desc->name, substream->pcm->name, sizeof(desc->name));
+ desc->type = MEDIA_ENT_T_DEVNODE_ALSA;
+ desc->alsa.card = card->number;
+ desc->alsa.device = substream->pcm->device;
+ desc->alsa.subdevice = substream->number;
+
+ return 0;
+}
+
+int snd_pcm_media_entities_create(struct snd_pcm *pcm, int stream,
+ unsigned int id)
+{
+ struct snd_pcm_str *pstr = &pcm->streams[stream];
+ struct snd_pcm_substream *substream;
+ int err;
+
+ for (substream = pstr->substream;
+ substream;
+ substream = substream->next) {
+ err = snd_media_entity_create(
+ pcm->card, snd_pcm_get_entity_desc,
+ id + substream->number,
+ stream == SNDRV_PCM_STREAM_CAPTURE ? 1 : 0,
+ stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
+ substream);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(snd_pcm_media_entities_create);
+#endif
+
#ifdef CONFIG_PROC_FS
/*
* Info interface
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 04/11] ALSA: implement MEDIA_IOC_ENUM_LINKS (1)
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (2 preceding siblings ...)
2012-08-27 22:30 ` [RFC PATCH 03/11] ALSA: pcm: add ALSA PCM device entities Clemens Ladisch
@ 2012-08-27 22:31 ` Clemens Ladisch
2012-08-27 22:31 ` [RFC PATCH 05/11] ALSA: implement MEDIA_IOC_ENUM_LINKS (2) Clemens Ladisch
` (7 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:31 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Allow to retrieve pad information.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
sound/core/media.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/sound/core/media.c b/sound/core/media.c
index aa94175..96b09a3 100644
--- a/sound/core/media.c
+++ b/sound/core/media.c
@@ -161,6 +161,48 @@ static int snd_media_enum_entities(struct snd_card *card,
return copy_to_user(descp, &desc, sizeof(desc));
}
+static int snd_media_enum_links(struct snd_card *card,
+ struct media_links_enum __user *linksp)
+{
+ struct media_links_enum links;
+ struct snd_media_entity *entity;
+
+ if (copy_from_user(&links, linksp, sizeof(links)))
+ return -EFAULT;
+
+ mutex_lock(&card->media_mutex);
+ entity = search_entity(card, links.entity);
+ mutex_unlock(&card->media_mutex);
+ if (!entity)
+ return -EINVAL;
+
+ if (links.pads) {
+ struct media_pad_desc pad;
+ unsigned int i;
+
+ memset(&pad, 0, sizeof(pad));
+ pad.entity = entity->id;
+
+ pad.flags = MEDIA_PAD_FL_SINK;
+ for (i = 0; i < entity->sinks; i++) {
+ if (copy_to_user(links.pads, &pad, sizeof(pad)))
+ return -EFAULT;
+ links.pads++;
+ pad.index++;
+ }
+
+ pad.flags = MEDIA_PAD_FL_SOURCE;
+ for (i = 0; i < entity->sources; i++) {
+ if (copy_to_user(links.pads, &pad, sizeof(pad)))
+ return -EFAULT;
+ links.pads++;
+ pad.index++;
+ }
+ }
+
+ return 0;
+}
+
static int snd_media_control_ioctl(struct snd_card *card,
struct snd_ctl_file *ctl_file,
unsigned int cmd, unsigned long arg)
@@ -172,6 +214,8 @@ static int snd_media_control_ioctl(struct snd_card *card,
return snd_media_device_info(card, argp);
case MEDIA_IOC_ENUM_ENTITIES:
return snd_media_enum_entities(card, argp);
+ case MEDIA_IOC_ENUM_LINKS:
+ return snd_media_enum_links(card, argp);
default:
return -ENOIOCTLCMD;
}
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 05/11] ALSA: implement MEDIA_IOC_ENUM_LINKS (2)
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (3 preceding siblings ...)
2012-08-27 22:31 ` [RFC PATCH 04/11] ALSA: implement MEDIA_IOC_ENUM_LINKS (1) Clemens Ladisch
@ 2012-08-27 22:31 ` Clemens Ladisch
2012-08-27 22:32 ` [RFC PATCH 06/11] ALSA: implement MEDIA_IOC_SETUP_LINK Clemens Ladisch
` (6 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:31 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Allow drivers to create links between entities.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
include/sound/core.h | 3 ++
include/sound/media.h | 11 ++++++
sound/core/media.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/include/sound/core.h b/include/sound/core.h
index 072b642..f6577ec 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -43,6 +43,7 @@ struct module;
struct device;
struct device_attribute;
struct snd_media_card_ops;
+struct snd_media_link;
/* device allocation stuff */
@@ -152,6 +153,8 @@ struct snd_card {
const struct snd_media_card_ops *media_ops;
struct mutex media_mutex;
struct list_head media_entities;
+ unsigned int media_links_count;
+ struct snd_media_link *media_links;
#endif
};
diff --git a/include/sound/media.h b/include/sound/media.h
index 65dd068..ebb7c7d 100644
--- a/include/sound/media.h
+++ b/include/sound/media.h
@@ -44,6 +44,11 @@ int snd_media_entity_create(struct snd_card *card,
unsigned int id,
unsigned int sinks, unsigned int sources,
void *private_data);
+int snd_media_link_create(struct snd_card *card,
+ unsigned int source_entity,
+ unsigned int source_pad,
+ unsigned int sink_entity,
+ unsigned int sink_pad);
int snd_media_create(struct snd_card *card);
void __init snd_media_init(void);
@@ -59,6 +64,12 @@ static inline int snd_media_entity_create(struct snd_card *card,
unsigned int sinks, unsigned int sources,
void *private_data)
{ return 0; }
+static inline int snd_media_link_create(struct snd_card *card,
+ unsigned int source_entity,
+ unsigned int source_pad,
+ unsigned int sink_entity,
+ unsigned int sink_pad)
+{ return 0; }
static inline int snd_media_create(struct snd_card *card)
diff --git a/sound/core/media.c b/sound/core/media.c
index 96b09a3..aa90848 100644
--- a/sound/core/media.c
+++ b/sound/core/media.c
@@ -36,6 +36,13 @@ struct snd_media_entity {
unsigned int sinks, sources;
};
+struct snd_media_link {
+ unsigned int source_entity;
+ unsigned int sink_entity;
+ unsigned short source_pad;
+ unsigned short sink_pad;
+};
+
static struct snd_media_entity *search_entity(struct snd_card *card,
unsigned int id)
{
@@ -82,6 +89,47 @@ int snd_media_entity_create(struct snd_card *card,
}
EXPORT_SYMBOL(snd_media_entity_create);
+int snd_media_link_create(struct snd_card *card,
+ unsigned int source_entity,
+ unsigned int source_pad,
+ unsigned int sink_entity,
+ unsigned int sink_pad)
+{
+ struct snd_media_link link;
+ struct snd_media_link *links;
+ size_t new_size = 0;
+
+ link.source_entity = source_entity;
+ link.sink_entity = sink_entity;
+ link.source_pad = source_pad;
+ link.sink_pad = sink_pad;
+
+ mutex_lock(&card->media_mutex);
+
+ if (card->media_links) {
+ size_t allocated = ksize(card->media_links);
+ if (allocated < (card->media_links_count + 1) * sizeof(link))
+ new_size = allocated * 2;
+ } else {
+ new_size = 4 * sizeof(link);
+ }
+ if (new_size > 0) {
+ links = krealloc(card->media_links, new_size, GFP_KERNEL);
+ if (!links) {
+ mutex_unlock(&card->media_mutex);
+ return -ENOMEM;
+ }
+ card->media_links = links;
+ }
+
+ card->media_links[card->media_links_count++] = link;
+
+ mutex_unlock(&card->media_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(snd_media_link_create);
+
static int snd_media_dev_free(struct snd_device *device)
{
struct snd_card *card = device->device_data;
@@ -94,6 +142,8 @@ static int snd_media_dev_free(struct snd_device *device)
kfree(e);
}
+ kfree(card->media_links);
+
return 0;
}
@@ -136,6 +186,7 @@ static int snd_media_enum_entities(struct snd_card *card,
{
struct media_entity_desc desc;
struct snd_media_entity *entity;
+ unsigned int i;
int err;
if (copy_from_user(&desc, descp, sizeof(desc)))
@@ -152,7 +203,13 @@ static int snd_media_enum_entities(struct snd_card *card,
desc.flags = 0;
desc.group_id = 0;
desc.pads = entity->sinks + entity->sources;
+
desc.links = 0;
+ mutex_lock(&card->media_mutex);
+ for (i = 0; i < card->media_links_count; i++)
+ if (card->media_links[i].source_entity == desc.id)
+ desc.links++;
+ mutex_unlock(&card->media_mutex);
err = entity->get_desc(card, entity->private_data, &desc);
if (err < 0)
@@ -200,6 +257,35 @@ static int snd_media_enum_links(struct snd_card *card,
}
}
+ if (links.links) {
+ struct media_link_desc desc;
+ struct snd_media_link *link;
+ unsigned int i;
+
+ memset(&desc, 0, sizeof(desc));
+ desc.source.entity = links.entity;
+ desc.source.flags = MEDIA_PAD_FL_SOURCE;
+ desc.sink.flags = MEDIA_PAD_FL_SINK;
+ desc.flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
+
+ mutex_lock(&card->media_mutex);
+ for (i = 0; i < card->media_links_count; i++) {
+ link = &card->media_links[i];
+ if (link->source_entity != links.entity)
+ continue;
+
+ desc.source.index = link->source_pad;
+ desc.sink.entity = link->sink_entity;
+ desc.sink.index = link->sink_pad;
+ if (copy_to_user(links.links, &desc, sizeof(desc))) {
+ mutex_unlock(&card->media_mutex);
+ return -EFAULT;
+ }
+ links.links++;
+ }
+ mutex_unlock(&card->media_mutex);
+ }
+
return 0;
}
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 06/11] ALSA: implement MEDIA_IOC_SETUP_LINK
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (4 preceding siblings ...)
2012-08-27 22:31 ` [RFC PATCH 05/11] ALSA: implement MEDIA_IOC_ENUM_LINKS (2) Clemens Ladisch
@ 2012-08-27 22:32 ` Clemens Ladisch
2012-08-27 22:33 ` [RFC PATCH 07/11] [media] media: add entity types for ALSA Clemens Ladisch
` (5 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:32 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Just for compatibility with the media controller API, implement the
setup link ioctl, which does not actually do anything.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
sound/core/media.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/sound/core/media.c b/sound/core/media.c
index aa90848..cbc51d9 100644
--- a/sound/core/media.c
+++ b/sound/core/media.c
@@ -289,6 +289,45 @@ static int snd_media_enum_links(struct snd_card *card,
return 0;
}
+static int snd_media_setup_link(struct snd_card *card,
+ struct media_link_desc __user *descp)
+{
+ struct media_link_desc desc;
+ struct snd_media_entity *source, *sink;
+ struct snd_media_link *link;
+ unsigned int i;
+ int err;
+
+ if (copy_from_user(&desc, descp, sizeof(desc)))
+ return -EFAULT;
+
+ if (desc.flags != (MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE))
+ return -EINVAL;
+
+ mutex_lock(&card->media_mutex);
+ source = search_entity(card, desc.source.entity);
+ sink = search_entity(card, desc.sink.entity);
+ mutex_unlock(&card->media_mutex);
+ if (!source || !sink)
+ return -EINVAL;
+
+ err = -EINVAL;
+ mutex_lock(&card->media_mutex);
+ for (i = 0; i < card->media_links_count; i++) {
+ link = &card->media_links[i];
+ if (link->source_entity == desc.source.entity &&
+ link->sink_entity == desc.sink.entity &&
+ link->source_pad == desc.source.index &&
+ link->sink_pad == desc.sink.index) {
+ err = 0;
+ break;
+ }
+ }
+ mutex_unlock(&card->media_mutex);
+
+ return err;
+}
+
static int snd_media_control_ioctl(struct snd_card *card,
struct snd_ctl_file *ctl_file,
unsigned int cmd, unsigned long arg)
@@ -302,6 +341,8 @@ static int snd_media_control_ioctl(struct snd_card *card,
return snd_media_enum_entities(card, argp);
case MEDIA_IOC_ENUM_LINKS:
return snd_media_enum_links(card, argp);
+ case MEDIA_IOC_SETUP_LINK:
+ return snd_media_setup_link(card, argp);
default:
return -ENOIOCTLCMD;
}
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 07/11] [media] media: add entity types for ALSA
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (5 preceding siblings ...)
2012-08-27 22:32 ` [RFC PATCH 06/11] ALSA: implement MEDIA_IOC_SETUP_LINK Clemens Ladisch
@ 2012-08-27 22:33 ` Clemens Ladisch
2012-08-27 22:33 ` [RFC PATCH 08/11] ALSA: usb-audio: implement card get_info callback Clemens Ladisch
` (4 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:33 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Add entity types for describing the topology of sound devices.
JACK entities represent connections to the outside world. Properties of
the jack will be described by a TLV on the jack entity.
MIXER entities add their inputs together, while SELECTOR entities route
on of their inputs to the output. PROCESSING entities represent volume/
mute controls or other effects processing units. These entities may
have ALSA controls associated with them, which is indicated by those
controls having a TLV containing the entity ID and the control type.
SPLIT and MERGE entities are needed for HDA codecs, whose topology is
constructed of stereo channel pairs.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
include/linux/media.h | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/include/linux/media.h b/include/linux/media.h
index 0ef8833..9d2ad75 100644
--- a/include/linux/media.h
+++ b/include/linux/media.h
@@ -57,6 +57,15 @@ struct media_device_info {
#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2)
#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3)
+#define MEDIA_ENT_T_JACK (3 << MEDIA_ENT_TYPE_SHIFT)
+
+#define MEDIA_ENT_T_ALSA (4 << MEDIA_ENT_TYPE_SHIFT)
+#define MEDIA_ENT_T_ALSA_MIXER (MEDIA_ENT_T_ALSA + 1)
+#define MEDIA_ENT_T_ALSA_SELECTOR (MEDIA_ENT_T_ALSA + 2)
+#define MEDIA_ENT_T_ALSA_PROCESSING (MEDIA_ENT_T_ALSA + 3)
+#define MEDIA_ENT_T_ALSA_SPLIT (MEDIA_ENT_T_ALSA + 4)
+#define MEDIA_ENT_T_ALSA_MERGE (MEDIA_ENT_T_ALSA + 5)
+
#define MEDIA_ENT_FL_DEFAULT (1 << 0)
struct media_entity_desc {
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 08/11] ALSA: usb-audio: implement card get_info callback
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (6 preceding siblings ...)
2012-08-27 22:33 ` [RFC PATCH 07/11] [media] media: add entity types for ALSA Clemens Ladisch
@ 2012-08-27 22:33 ` Clemens Ladisch
2012-08-27 22:34 ` [RFC PATCH 09/11] ALSA: usb-audio: create PCM device entities Clemens Ladisch
` (3 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:33 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Add a helper for retrieving information about USB devices.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
include/sound/media.h | 16 ++++++++++++++++
sound/core/media.c | 28 ++++++++++++++++++++++++++++
sound/usb/card.c | 2 ++
3 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/include/sound/media.h b/include/sound/media.h
index ebb7c7d..5339acb 100644
--- a/include/sound/media.h
+++ b/include/sound/media.h
@@ -39,6 +39,15 @@ typedef int (*snd_media_entity_get_desc_t)(struct snd_card *card,
#define snd_card_set_media_ops(card, ops) ((card)->media_ops = (ops))
+#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
+int snd_media_get_usb_card_info(struct snd_card *card,
+ struct media_device_info *info);
+
+extern const struct snd_media_card_ops snd_media_default_usb_ops;
+#define snd_card_set_media_ops_default_usb(card) \
+ snd_card_set_media_ops((card), &snd_media_default_usb_ops)
+#endif
+
int snd_media_entity_create(struct snd_card *card,
snd_media_entity_get_desc_t get_desc,
unsigned int id,
@@ -58,6 +67,13 @@ void __exit snd_media_exit(void);
#define snd_card_set_media_ops(card, ops)
+#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
+#define snd_card_set_media_ops_default_usb(card)
+static inline int snd_media_get_usb_card_info(struct snd_card *card,
+ struct media_device_info *info)
+{ return 0; }
+#endif
+
static inline int snd_media_entity_create(struct snd_card *card,
snd_media_entity_get_desc_t get_desc,
unsigned int id,
diff --git a/sound/core/media.c b/sound/core/media.c
index cbc51d9..f42e00b 100644
--- a/sound/core/media.c
+++ b/sound/core/media.c
@@ -24,6 +24,7 @@
#include <linux/media.h>
#include <linux/string.h>
#include <linux/uaccess.h>
+#include <linux/usb.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/media.h>
@@ -328,6 +329,33 @@ static int snd_media_setup_link(struct snd_card *card,
return err;
}
+#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
+int snd_media_get_usb_card_info(struct snd_card *card,
+ struct media_device_info *info)
+{
+ struct usb_interface *intf;
+ struct usb_device *usb;
+
+ if (snd_BUG_ON(!card->dev))
+ return -ENXIO;
+ intf = to_usb_interface(card->dev);
+ usb = interface_to_usbdev(intf);
+
+ if (usb->serial)
+ strlcpy(info->serial, usb->serial, sizeof(info->serial));
+ usb_make_path(usb, info->bus_info, sizeof(info->bus_info));
+ info->hw_revision = le16_to_cpu(usb->descriptor.bcdDevice);
+
+ return 0;
+}
+EXPORT_SYMBOL(snd_media_get_usb_card_info);
+
+const struct snd_media_card_ops snd_media_default_usb_ops = {
+ .get_info = snd_media_get_usb_card_info,
+};
+EXPORT_SYMBOL(snd_media_default_usb_ops);
+#endif
+
static int snd_media_control_ioctl(struct snd_card *card,
struct snd_ctl_file *ctl_file,
unsigned int cmd, unsigned long arg)
diff --git a/sound/usb/card.c b/sound/usb/card.c
index d5b5c33..311366b 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -52,6 +52,7 @@
#include <sound/control.h>
#include <sound/core.h>
#include <sound/info.h>
+#include <sound/media.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
@@ -490,6 +491,7 @@ snd_usb_audio_probe(struct usb_device *dev,
goto __error;
}
snd_card_set_dev(chip->card, &intf->dev);
+ snd_card_set_media_ops_default_usb(chip->card);
chip->pm_intf = intf;
break;
}
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 09/11] ALSA: usb-audio: create PCM device entities
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (7 preceding siblings ...)
2012-08-27 22:33 ` [RFC PATCH 08/11] ALSA: usb-audio: implement card get_info callback Clemens Ladisch
@ 2012-08-27 22:34 ` Clemens Ladisch
2012-08-27 22:35 ` [RFC PATCH 10/11] ALSA: usb-audio: add terminal/unit entities and links Clemens Ladisch
` (2 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:34 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
sound/usb/quirks.c | 4 ++--
sound/usb/stream.c | 16 +++++++++++-----
sound/usb/stream.h | 1 +
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 2781726..293b4ba 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -152,7 +152,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
stream = (fp->endpoint & USB_DIR_IN)
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- err = snd_usb_add_audio_stream(chip, stream, fp);
+ err = snd_usb_add_audio_stream(chip, stream, 0, fp);
if (err < 0) {
kfree(fp);
kfree(rate_table);
@@ -258,7 +258,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
stream = (fp->endpoint & USB_DIR_IN)
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- err = snd_usb_add_audio_stream(chip, stream, fp);
+ err = snd_usb_add_audio_stream(chip, stream, 0, fp);
if (err < 0) {
kfree(fp);
return err;
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index e166eb5..145324d 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -78,7 +78,7 @@ static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
*/
static void snd_usb_init_substream(struct snd_usb_stream *as,
- int stream,
+ int stream, u8 terminal_id,
struct audioformat *fp)
{
struct snd_usb_substream *subs = &as->substream[stream];
@@ -98,6 +98,9 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
subs->num_formats++;
subs->fmt_type = fp->fmt_type;
subs->ep_num = fp->endpoint;
+
+ if (terminal_id > 0)
+ snd_pcm_media_entities_create(as->pcm, stream, terminal_id);
}
/*
@@ -106,7 +109,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
* if not, create a new pcm stream.
*/
int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
- int stream,
+ int stream, u8 terminal_id,
struct audioformat *fp)
{
struct list_head *p;
@@ -138,7 +141,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
err = snd_pcm_new_stream(as->pcm, stream, 1);
if (err < 0)
return err;
- snd_usb_init_substream(as, stream, fp);
+ snd_usb_init_substream(as, stream, terminal_id, fp);
return 0;
}
@@ -166,7 +169,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
else
strcpy(pcm->name, "USB Audio");
- snd_usb_init_substream(as, stream, fp);
+ snd_usb_init_substream(as, stream, terminal_id, fp);
list_add(&as->list, &chip->pcm_list);
chip->pcm_devs++;
@@ -260,6 +263,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
struct audioformat *fp = NULL;
int num, protocol, clock = 0;
struct uac_format_type_i_continuous_descriptor *fmt;
+ u8 terminal_id = 0;
dev = chip->dev;
@@ -324,6 +328,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
}
format = le16_to_cpu(as->wFormatTag); /* remember the format value */
+ terminal_id = as->bTerminalLink;
break;
}
@@ -347,6 +352,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
num_channels = as->bNrChannels;
format = le32_to_cpu(as->bmFormats);
+ terminal_id = as->bTerminalLink;
/* lookup the terminal associated to this interface
* to extract the clock */
@@ -460,7 +466,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
}
snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
- err = snd_usb_add_audio_stream(chip, stream, fp);
+ err = snd_usb_add_audio_stream(chip, stream, terminal_id, fp);
if (err < 0) {
kfree(fp->rate_table);
kfree(fp);
diff --git a/sound/usb/stream.h b/sound/usb/stream.h
index c97f679..31f17c0 100644
--- a/sound/usb/stream.h
+++ b/sound/usb/stream.h
@@ -6,6 +6,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
int stream,
+ u8 terminal_id,
struct audioformat *fp);
#endif /* __USBAUDIO_STREAM_H */
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 10/11] ALSA: usb-audio: add terminal/unit entities and links
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (8 preceding siblings ...)
2012-08-27 22:34 ` [RFC PATCH 09/11] ALSA: usb-audio: create PCM device entities Clemens Ladisch
@ 2012-08-27 22:35 ` Clemens Ladisch
2012-08-27 22:36 ` [RFC PATCH 11/11] ALSA: hda-intel: implement card get_info callback Clemens Ladisch
2012-09-04 15:56 ` [RFC PATCH 1/11] expose sound device topology information Takashi Iwai
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:35 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Use the terminal/unit descriptors to create entities and links.
(This should be integrated with parse_audio_unit(), but that function
does not yet support all unit types.)
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
sound/usb/mixer.c | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 278 insertions(+), 0 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 4f40ba8..a5fa807 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -45,6 +45,7 @@
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/media.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/usb.h>
@@ -55,6 +56,7 @@
#include <sound/control.h>
#include <sound/hwdep.h>
#include <sound/info.h>
+#include <sound/media.h>
#include <sound/tlv.h>
#include "usbaudio.h"
@@ -1969,6 +1971,278 @@ static int snd_usb_mixer_dev_free(struct snd_device *device)
return 0;
}
+static void unit_name(struct media_entity_desc *entity,
+ const u8 *desc, const char *prefix)
+{
+ /* TODO: read the terminal name from the device */
+ sprintf(entity->name, "%s%u", prefix, desc[3]);
+}
+
+static int input_terminal_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "IT");
+ desc->type = MEDIA_ENT_T_JACK;
+ return 0;
+}
+
+static int output_terminal_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "OT");
+ desc->type = MEDIA_ENT_T_JACK;
+ return 0;
+}
+
+static int mixer_unit_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "MU");
+ desc->type = MEDIA_ENT_T_ALSA_MIXER;
+ return 0;
+}
+
+static int selector_unit_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "SU");
+ desc->type = MEDIA_ENT_T_ALSA_SELECTOR;
+ return 0;
+}
+
+static int feature_unit_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "FU");
+ desc->type = MEDIA_ENT_T_ALSA_PROCESSING;
+ return 0;
+}
+
+static int processing_unit_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "PU");
+ desc->type = MEDIA_ENT_T_ALSA_PROCESSING;
+ return 0;
+}
+
+static int extension_unit_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "XU");
+ desc->type = MEDIA_ENT_T_ALSA_PROCESSING;
+ return 0;
+}
+
+static int effect_unit_v2_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "EU");
+ desc->type = MEDIA_ENT_T_ALSA_PROCESSING;
+ return 0;
+}
+
+static int src_v2_get_desc(struct snd_card *card,
+ void *private_data,
+ struct media_entity_desc *desc)
+{
+ unit_name(desc, private_data, "SRC");
+ desc->type = MEDIA_ENT_T_ALSA_PROCESSING;
+ return 0;
+}
+
+static int snd_usb_mixer_entity(struct mixer_build *state, const u8 *desc)
+{
+ snd_media_entity_get_desc_t get_desc = NULL;
+ unsigned int sinks = 0, sources = 0, source_ids_count = 0, i;
+ const u8 *source_ids = NULL;
+ u8 source_id = 0;
+ int err;
+
+ if (desc[0] < 4)
+ return 0;
+
+ if (state->mixer->protocol == UAC_VERSION_1) {
+ switch (desc[2]) {
+ case UAC_INPUT_TERMINAL:
+ if (desc[0] >= 6 &&
+ desc[5] != (UAC_TERMINAL_STREAMING >> 8)) {
+ get_desc = &input_terminal_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC_OUTPUT_TERMINAL:
+ if (desc[0] >= 8) {
+ source_id = desc[7];
+ if (desc[5] != (UAC_TERMINAL_STREAMING >> 8))
+ get_desc = &output_terminal_get_desc;
+ }
+ break;
+ case UAC_MIXER_UNIT:
+ if (desc[0] >= 6) {
+ source_ids = &desc[5];
+ get_desc = &mixer_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC_SELECTOR_UNIT:
+ if (desc[0] >= 6) {
+ source_ids = &desc[5];
+ get_desc = &selector_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC_FEATURE_UNIT:
+ if (desc[0] >= 5) {
+ source_id = desc[4];
+ get_desc = &feature_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC1_PROCESSING_UNIT:
+ if (desc[0] >= 8) {
+ source_ids = &desc[7];
+ get_desc = &processing_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC1_EXTENSION_UNIT:
+ if (desc[0] >= 7 && desc[0] >= 7 + desc[6]) {
+ source_ids_count = desc[6];
+ source_ids = &desc[7];
+ get_desc = &extension_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ }
+ } else {
+ switch (desc[2]) {
+ case UAC_INPUT_TERMINAL:
+ if (desc[0] >= 6 &&
+ desc[5] != (UAC_TERMINAL_STREAMING >> 8)) {
+ get_desc = &input_terminal_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC_OUTPUT_TERMINAL:
+ if (desc[0] >= 8) {
+ source_id = desc[7];
+ if (desc[5] != (UAC_TERMINAL_STREAMING >> 8))
+ get_desc = &output_terminal_get_desc;
+ }
+ break;
+ case UAC_MIXER_UNIT:
+ if (desc[0] >= 5 && desc[0] >= 5 + desc[4]) {
+ source_ids_count = desc[4];
+ source_ids = &desc[5];
+ get_desc = &mixer_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC_SELECTOR_UNIT:
+ if (desc[0] >= 5 && desc[0] >= 5 + desc[4]) {
+ source_ids_count = desc[4];
+ source_ids = &desc[5];
+ get_desc = &selector_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC_FEATURE_UNIT:
+ if (desc[0] >= 5) {
+ source_id = desc[4];
+ get_desc = &feature_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC2_EFFECT_UNIT:
+ if (desc[0] >= 7) {
+ source_id = desc[6];
+ get_desc = &effect_unit_v2_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC2_PROCESSING_UNIT_V2:
+ if (desc[0] >= 7 && desc[0] >= 7 + desc[6]) {
+ source_ids_count = desc[6];
+ source_ids = &desc[7];
+ get_desc = &processing_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC2_EXTENSION_UNIT_V2:
+ if (desc[0] >= 7 && desc[0] >= 7 + desc[6]) {
+ source_ids_count = desc[6];
+ source_ids = &desc[7];
+ get_desc = &extension_unit_get_desc;
+ sources = 1;
+ }
+ break;
+ case UAC2_SAMPLE_RATE_CONVERTER:
+ if (desc[0] >= 5) {
+ source_id = desc[4];
+ get_desc = &src_v2_get_desc;
+ sources = 1;
+ }
+ break;
+ }
+ }
+
+ if (source_id != 0) {
+ err = snd_media_link_create(state->chip->card,
+ source_id, 0, desc[3], 0);
+ if (err < 0)
+ return err;
+ sinks = 1;
+ }
+ else if (source_ids != NULL) {
+ if (source_ids_count == 0 &&
+ source_ids + source_ids_count <= desc + desc[0])
+ source_ids_count = desc + desc[0] - source_ids;
+ for (i = 0; i < source_ids_count; i++) {
+ err = snd_media_link_create(state->chip->card,
+ source_ids[i], 0,
+ desc[3], i);
+ if (err < 0)
+ return err;
+ }
+ sinks = source_ids_count;
+ }
+
+ if (get_desc) {
+ err = snd_media_entity_create(state->chip->card, get_desc,
+ desc[3], sinks, sources,
+ (void *)desc);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int snd_usb_mixer_entities(struct mixer_build *state)
+{
+ void *p;
+ int err;
+
+ p = NULL;
+ while ((p = snd_usb_find_desc(state->mixer->hostif->extra,
+ state->mixer->hostif->extralen,
+ p, USB_DT_CS_INTERFACE)) != NULL) {
+ err = snd_usb_mixer_entity(state, p);
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
/*
* create mixer controls
*
@@ -1997,6 +2271,10 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
}
}
+ err = snd_usb_mixer_entities(&state);
+ if (err < 0)
+ return err;
+
p = NULL;
while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen,
p, UAC_OUTPUT_TERMINAL)) != NULL) {
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 11/11] ALSA: hda-intel: implement card get_info callback
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (9 preceding siblings ...)
2012-08-27 22:35 ` [RFC PATCH 10/11] ALSA: usb-audio: add terminal/unit entities and links Clemens Ladisch
@ 2012-08-27 22:36 ` Clemens Ladisch
2012-09-04 15:56 ` [RFC PATCH 1/11] expose sound device topology information Takashi Iwai
11 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-08-27 22:36 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown, alsa-devel
Add a helper for retrieving information about PCI devices.
(Codec topology information is not yet implemented.)
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
include/sound/media.h | 16 ++++++++++++++++
sound/core/media.c | 36 ++++++++++++++++++++++++++++++++++++
sound/pci/hda/hda_intel.c | 2 ++
3 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/include/sound/media.h b/include/sound/media.h
index 5339acb..e030e4c 100644
--- a/include/sound/media.h
+++ b/include/sound/media.h
@@ -39,6 +39,15 @@ typedef int (*snd_media_entity_get_desc_t)(struct snd_card *card,
#define snd_card_set_media_ops(card, ops) ((card)->media_ops = (ops))
+#ifdef CONFIG_PCI
+int snd_media_get_pci_card_info(struct snd_card *card,
+ struct media_device_info *info);
+
+extern const struct snd_media_card_ops snd_media_default_pci_ops;
+#define snd_card_set_media_ops_default_pci(card) \
+ snd_card_set_media_ops((card), &snd_media_default_pci_ops)
+#endif
+
#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
int snd_media_get_usb_card_info(struct snd_card *card,
struct media_device_info *info);
@@ -67,6 +76,13 @@ void __exit snd_media_exit(void);
#define snd_card_set_media_ops(card, ops)
+#ifdef CONFIG_PCI
+#define snd_card_set_media_ops_default_pci(card)
+static inline int snd_media_get_pci_card_info(struct snd_card *card,
+ struct media_device_info *info)
+{ return 0; }
+#endif
+
#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
#define snd_card_set_media_ops_default_usb(card)
static inline int snd_media_get_usb_card_info(struct snd_card *card,
diff --git a/sound/core/media.c b/sound/core/media.c
index f42e00b..9da058d 100644
--- a/sound/core/media.c
+++ b/sound/core/media.c
@@ -18,10 +18,12 @@
*/
#include <linux/device.h>
+#include <linux/export.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/media.h>
+#include <linux/pci.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
@@ -329,6 +331,40 @@ static int snd_media_setup_link(struct snd_card *card,
return err;
}
+#ifdef CONFIG_PCI
+int snd_media_get_pci_card_info(struct snd_card *card,
+ struct media_device_info *info)
+{
+ struct pci_dev *pci;
+
+ if (snd_BUG_ON(!card->dev))
+ return -ENXIO;
+ pci = to_pci_dev(card->dev);
+
+ if (pci_is_pcie(pci)) {
+ int pos = pci_find_ext_capability(pci, PCI_EXT_CAP_ID_DSN);
+ if (pos) {
+ u32 eui[2];
+
+ pci_read_config_dword(pci, pos + 4, &eui[0]);
+ pci_read_config_dword(pci, pos + 8, &eui[1]);
+ sprintf(info->serial, "%08x%08x", eui[1], eui[0]);
+ }
+ }
+ snprintf(info->bus_info, sizeof(info->bus_info), "%s:%s",
+ pci_is_pcie(pci) ? "PCIe" : "PCI", pci_name(pci));
+ info->hw_revision = pci->revision;
+
+ return 0;
+}
+EXPORT_SYMBOL(snd_media_get_pci_card_info);
+
+const struct snd_media_card_ops snd_media_default_pci_ops = {
+ .get_info = snd_media_get_pci_card_info,
+};
+EXPORT_SYMBOL(snd_media_default_pci_ops);
+#endif
+
#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
int snd_media_get_usb_card_info(struct snd_card *card,
struct media_device_info *info)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 1c9c779..a01a43c 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -54,6 +54,7 @@
#endif
#include <sound/core.h>
#include <sound/initval.h>
+#include <sound/media.h>
#include <linux/vgaarb.h>
#include <linux/vga_switcheroo.h>
#include <linux/firmware.h>
@@ -3305,6 +3306,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
}
snd_card_set_dev(card, &pci->dev);
+ snd_card_set_media_ops_default_pci(card);
err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
if (err < 0)
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 1/11] expose sound device topology information
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
` (10 preceding siblings ...)
2012-08-27 22:36 ` [RFC PATCH 11/11] ALSA: hda-intel: implement card get_info callback Clemens Ladisch
@ 2012-09-04 15:56 ` Takashi Iwai
2012-09-04 18:02 ` Clemens Ladisch
11 siblings, 1 reply; 17+ messages in thread
From: Takashi Iwai @ 2012-09-04 15:56 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel, Mark Brown
Hi Clemens,
At Tue, 28 Aug 2012 00:28:30 +0200,
Clemens Ladisch wrote:
>
> Hi,
>
> these are some tentative patches to allow sound drivers to provide
> routing information to userspace. (So far, snd-usb-audio has a partial
> implementation; I haven't yet had time for snd-hda-intel. I haven't
> even looked at ASoC.)
Thanks for patches. This brought up interesting discussions at
Plumbers. We (kind of) agree that the media controller API can be
pretty suitable, and even Mark didn't grumble so much against it :)
It's a good sign.
> The media controller API <linux/media.h> allows prividing routing
> information, but its implementation does not quite fit the sound
> drivers:
> * it allows reconfiguration of links, but not in a way that would be
> useful for ALSA selector controls;
> * it allows drivers to access the entity graph and pipelines, which is
> not needed;
> * it is rather heavyweight.
>
> Therefore, these patches create their own implementation of the media
> controller API. In this implementation, all entity and link information
> is completely static, and more space-efficient.
I think this is fine for USB-audio and HD-audio. We don't expect that
the changes are done via media controller API but it'll provide just
some mapping. But, possible embedded guys might want to make it
configurable. (Well, in that case, they can reimplement the full
stack based on the original media controller helper code...)
Maybe Mark can give more comments on it.
> For simplicity, the ioctls hook into the ALSA control device instead
> of creating a new /dev/media* device.
This is OK, I think. But what about multiple codecs on a single
control device? Can they be represented well?
> The separate implementation does not allow sharing of one media
> controller device in the case of combined audio/video devices. However,
> separate drivers would already be a problem for HDMI outputs (GPU and
> sound); it appears we might need some mechanism to connect the
> topologies of multiple media devices.
The connection between different devices could be done in a different
way. For example, we may provide some Linux device tree connection.
(This reminds me of a TODO -- the implementation of standard Linux
device model to ALSA components, BTW.)
> TLVs (for jack entities, and for associating controls with entities)
> are not yet defined.
OK, this is a big missing piece. But it should be relatively easy.
Takashi
> Example output for my simple UA-1A device (not all information is
> decoded correctly):
>
> $ media-ctl -p -d /dev/snd/controlC5
> Opening media device /dev/snd/controlC5
> Enumerating entities
> Found 4 entities
> Enumerating pads and links
> Media controller API version 0.0.0
>
> Media device information
> ------------------------
> driver snd-usb-audio
> model EDIROL UA-1A
> serial
> bus info usb-0000:00:12.2-4.3
> hw revision 0x101
> driver version 0.0.0
>
> Device topology
> - entity 1: USB Audio (1 pad, 1 link)
> type Node subtype ALSA
> device node name /dev/tty (should be hw:5,0,0)
> pad0: Source
> -> "OT3":0 [ENABLED,IMMUTABLE]
>
> - entity 3: OT3 (1 pad, 1 link)
> type Unknown subtype Unknown (should be Jack)
> pad0: Sink
> <- "USB Audio":0 [ENABLED,IMMUTABLE]
>
> - entity 4: IT4 (1 pad, 1 link)
> type Unknown subtype Unknown
> pad0: Source
> -> "USB Audio":0 [ENABLED,IMMUTABLE]
>
> - entity 7: USB Audio (1 pad, 1 link)
> type Node subtype ALSA
> device node name /dev/tty
> pad0: Sink
> <- "IT4":0 [ENABLED,IMMUTABLE]
>
>
> include/linux/media.h | 9
> include/sound/core.h | 13 +
> include/sound/media.h | 116 ++++++++++
> include/sound/pcm.h | 6
> sound/core/Kconfig | 7
> sound/core/Makefile | 1
> sound/core/init.c | 4
> sound/core/media.c | 425 ++++++++++++++++++++++++++++++++++++++
> sound/core/pcm.c | 46 ++++
> sound/core/sound.c | 3
> sound/pci/hda/hda_intel.c | 2
> sound/usb/card.c | 2
> sound/usb/mixer.c | 278 ++++++++++++++++++++++++
> sound/usb/quirks.c | 4
> sound/usb/stream.c | 16 -
> sound/usb/stream.h | 1
> 16 files changed, 925 insertions(+), 8 deletions(-)
>
>
> Regards,
> Clemens
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 1/11] expose sound device topology information
2012-09-04 15:56 ` [RFC PATCH 1/11] expose sound device topology information Takashi Iwai
@ 2012-09-04 18:02 ` Clemens Ladisch
0 siblings, 0 replies; 17+ messages in thread
From: Clemens Ladisch @ 2012-09-04 18:02 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown
Takashi Iwai wrote:
> Clemens Ladisch wrote:
>> The media controller API <linux/media.h> allows prividing routing
>> information, but its implementation does not quite fit the sound
>> drivers:
>> * it allows reconfiguration of links, but not in a way that would be
>> useful for ALSA selector controls
I didn't mention why: it is not possible to enable two links to a sink
pad, and neither can one change the state of two links atomically;
therefore, an enum control with exactly one active input cannot be
modelled. (It might be possible to change the media controller API to
allow this.)
Mute controls _could_ be modelled by disabling links, but with all other
mixer control types not represented in the media controller API, this
doesn't appear to be very useful.
> But what about multiple codecs on a single control device? Can they
> be represented well?
The driver has to choose the entity IDs so that they don't conflict;
something like busnumber<<20 | codecaddress<<10 | nodeid.
The USB audio driver will have this problem if there are multiple audio
control interfaces, so I guess it will have to include the interface
number.
Regards,
Clemens
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO
2012-08-27 22:29 ` [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO Clemens Ladisch
@ 2012-09-07 2:13 ` Mark Brown
2012-09-07 7:14 ` Clemens Ladisch
0 siblings, 1 reply; 17+ messages in thread
From: Mark Brown @ 2012-09-07 2:13 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: Takashi Iwai, alsa-devel
On Tue, Aug 28, 2012 at 12:29:33AM +0200, Clemens Ladisch wrote:
> +config SND_MEDIA
> + bool "Media Controller API (EXPERIMENTAL)"
> + depends on EXPERIMENTAL
> + help
> + Say Y here to enable the media controller API, which allows to
> + retrieve the internal topology of sound devices.
I think there's a general consensus these days that EXPERIMENTAL is
pretty meaningless so we probably shouldn't bother with it. The text is
also a bit confusing, it enables use of the media controller API for
ALSA devices really.
I have to say I'm also a bit surprised that there's no core framework
for media controller and we're open coding ioctl() implementations here,
I'd have thought there would at least be a way of enumerating all media
controller devices in the system...
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO
2012-09-07 2:13 ` Mark Brown
@ 2012-09-07 7:14 ` Clemens Ladisch
2012-09-07 10:40 ` Takashi Iwai
0 siblings, 1 reply; 17+ messages in thread
From: Clemens Ladisch @ 2012-09-07 7:14 UTC (permalink / raw)
To: Mark Brown; +Cc: Takashi Iwai, alsa-devel
Mark Brown wrote:
> On Tue, Aug 28, 2012 at 12:29:33AM +0200, Clemens Ladisch wrote:
>> +config SND_MEDIA
>> + bool "Media Controller API (EXPERIMENTAL)"
>> + depends on EXPERIMENTAL
>> + help
>> + Say Y here to enable the media controller API, which allows to
>> + retrieve the internal topology of sound devices.
>
> I think there's a general consensus these days that EXPERIMENTAL is
> pretty meaningless so we probably shouldn't bother with it.
Well, I couldn't claim this to be any less experimental than the
implementation in drivers/media/. :)
> The text is also a bit confusing, it enables use of the media
> controller API for ALSA devices really.
It's in the ALSA menu. I could put "ALSA" in the title if it helps.
> I have to say I'm also a bit surprised that there's no core framework
> for media controller and we're open coding ioctl() implementations here,
drivers/media/media-*.c exists, but I did not use that implementation
because someone expressed concern about it being too heavyweight ...
> I'd have thought there would at least be a way of enumerating all media
> controller devices in the system...
It appears userspace is supposed to check all /dev/media* devices.
(Using /dev/snd/controlC* is just a makeshift arrangement; I'll have to
reuse some part of the media device registration framework, or tell udev
to create symlinks.)
Regards,
Clemens
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO
2012-09-07 7:14 ` Clemens Ladisch
@ 2012-09-07 10:40 ` Takashi Iwai
0 siblings, 0 replies; 17+ messages in thread
From: Takashi Iwai @ 2012-09-07 10:40 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel, Mark Brown
At Fri, 07 Sep 2012 09:14:30 +0200,
Clemens Ladisch wrote:
>
> Mark Brown wrote:
> > On Tue, Aug 28, 2012 at 12:29:33AM +0200, Clemens Ladisch wrote:
> >> +config SND_MEDIA
> >> + bool "Media Controller API (EXPERIMENTAL)"
> >> + depends on EXPERIMENTAL
> >> + help
> >> + Say Y here to enable the media controller API, which allows to
> >> + retrieve the internal topology of sound devices.
> >
> > I think there's a general consensus these days that EXPERIMENTAL is
> > pretty meaningless so we probably shouldn't bother with it.
>
> Well, I couldn't claim this to be any less experimental than the
> implementation in drivers/media/. :)
In the previous kernel summit, we agreed to drop CONFIG_EXPERIMENTAL
since it's just useless. So, no need to add yet another new entry
with that flag.
> > The text is also a bit confusing, it enables use of the media
> > controller API for ALSA devices really.
>
> It's in the ALSA menu. I could put "ALSA" in the title if it helps.
Yeah, I also prefer with that.
Takashi
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2012-09-07 10:40 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-27 22:28 [RFC PATCH 1/11] expose sound device topology information Clemens Ladisch
2012-08-27 22:29 ` [RFC PATCH 01/11] ALSA: implement MEDIA_IOC_DEVICE_INFO Clemens Ladisch
2012-09-07 2:13 ` Mark Brown
2012-09-07 7:14 ` Clemens Ladisch
2012-09-07 10:40 ` Takashi Iwai
2012-08-27 22:30 ` [RFC PATCH 02/11] ALSA: implement MEDIA_IOC_ENUM_ENTITIES Clemens Ladisch
2012-08-27 22:30 ` [RFC PATCH 03/11] ALSA: pcm: add ALSA PCM device entities Clemens Ladisch
2012-08-27 22:31 ` [RFC PATCH 04/11] ALSA: implement MEDIA_IOC_ENUM_LINKS (1) Clemens Ladisch
2012-08-27 22:31 ` [RFC PATCH 05/11] ALSA: implement MEDIA_IOC_ENUM_LINKS (2) Clemens Ladisch
2012-08-27 22:32 ` [RFC PATCH 06/11] ALSA: implement MEDIA_IOC_SETUP_LINK Clemens Ladisch
2012-08-27 22:33 ` [RFC PATCH 07/11] [media] media: add entity types for ALSA Clemens Ladisch
2012-08-27 22:33 ` [RFC PATCH 08/11] ALSA: usb-audio: implement card get_info callback Clemens Ladisch
2012-08-27 22:34 ` [RFC PATCH 09/11] ALSA: usb-audio: create PCM device entities Clemens Ladisch
2012-08-27 22:35 ` [RFC PATCH 10/11] ALSA: usb-audio: add terminal/unit entities and links Clemens Ladisch
2012-08-27 22:36 ` [RFC PATCH 11/11] ALSA: hda-intel: implement card get_info callback Clemens Ladisch
2012-09-04 15:56 ` [RFC PATCH 1/11] expose sound device topology information Takashi Iwai
2012-09-04 18:02 ` Clemens Ladisch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).