[ALSA] Add pcm_class attribute to PCM sysfs entry
This patch adds a new attribute, pcm_class, to each PCM sysfs entry. It's useful to detect what kind of PCM stream is, for example, HAL can check whether it's a modem or not. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
Родитель
a7da6ce564
Коммит
9d19f48cfe
|
@ -26,6 +26,7 @@
|
|||
#include <linux/mutex.h> /* struct mutex */
|
||||
#include <linux/rwsem.h> /* struct rw_semaphore */
|
||||
#include <linux/pm.h> /* pm_message_t */
|
||||
#include <linux/device.h>
|
||||
|
||||
/* forward declarations */
|
||||
#ifdef CONFIG_PCI
|
||||
|
@ -186,6 +187,7 @@ struct snd_minor {
|
|||
int device; /* device number */
|
||||
const struct file_operations *f_ops; /* file operations */
|
||||
void *private_data; /* private data for f_ops->open */
|
||||
struct class_device *class_dev; /* class device for sysfs */
|
||||
};
|
||||
|
||||
/* sound.c */
|
||||
|
@ -200,6 +202,8 @@ int snd_register_device(int type, struct snd_card *card, int dev,
|
|||
const char *name);
|
||||
int snd_unregister_device(int type, struct snd_card *card, int dev);
|
||||
void *snd_lookup_minor_data(unsigned int minor, int type);
|
||||
int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev,
|
||||
const struct class_device_attribute *attr);
|
||||
|
||||
#ifdef CONFIG_SND_OSSEMUL
|
||||
int snd_register_oss_device(int type, struct snd_card *card, int dev,
|
||||
|
|
|
@ -907,6 +907,28 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
|
|||
substream->pstr->substream_opened--;
|
||||
}
|
||||
|
||||
static ssize_t show_pcm_class(struct class_device *class_device, char *buf)
|
||||
{
|
||||
struct snd_pcm *pcm;
|
||||
const char *str;
|
||||
static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {
|
||||
[SNDRV_PCM_CLASS_GENERIC] = "generic",
|
||||
[SNDRV_PCM_CLASS_MULTI] = "multi",
|
||||
[SNDRV_PCM_CLASS_MODEM] = "modem",
|
||||
[SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",
|
||||
};
|
||||
|
||||
if (! (pcm = class_get_devdata(class_device)) ||
|
||||
pcm->dev_class > SNDRV_PCM_CLASS_LAST)
|
||||
str = "none";
|
||||
else
|
||||
str = strs[pcm->dev_class];
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", str);
|
||||
}
|
||||
|
||||
static struct class_device_attribute pcm_attrs =
|
||||
__ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL);
|
||||
|
||||
static int snd_pcm_dev_register(struct snd_device *device)
|
||||
{
|
||||
int cidx, err;
|
||||
|
@ -945,6 +967,8 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
|||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
snd_add_device_sysfs_file(devtype, pcm->card, pcm->device,
|
||||
&pcm_attrs);
|
||||
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
|
||||
snd_pcm_timer_init(substream);
|
||||
}
|
||||
|
|
|
@ -268,7 +268,11 @@ int snd_register_device(int type, struct snd_card *card, int dev,
|
|||
snd_minors[minor] = preg;
|
||||
if (card)
|
||||
device = card->dev;
|
||||
class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name);
|
||||
preg->class_dev = class_device_create(sound_class, NULL,
|
||||
MKDEV(major, minor),
|
||||
device, "%s", name);
|
||||
if (preg->class_dev)
|
||||
class_set_devdata(preg->class_dev, private_data);
|
||||
|
||||
mutex_unlock(&sound_mutex);
|
||||
return 0;
|
||||
|
@ -276,6 +280,24 @@ int snd_register_device(int type, struct snd_card *card, int dev,
|
|||
|
||||
EXPORT_SYMBOL(snd_register_device);
|
||||
|
||||
/* find the matching minor record
|
||||
* return the index of snd_minor, or -1 if not found
|
||||
*/
|
||||
static int find_snd_minor(int type, struct snd_card *card, int dev)
|
||||
{
|
||||
int cardnum, minor;
|
||||
struct snd_minor *mptr;
|
||||
|
||||
cardnum = card ? card->number : -1;
|
||||
for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor)
|
||||
if ((mptr = snd_minors[minor]) != NULL &&
|
||||
mptr->type == type &&
|
||||
mptr->card == cardnum &&
|
||||
mptr->device == dev)
|
||||
return minor;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_unregister_device - unregister the device on the given card
|
||||
* @type: the device type, SNDRV_DEVICE_TYPE_XXX
|
||||
|
@ -289,32 +311,42 @@ EXPORT_SYMBOL(snd_register_device);
|
|||
*/
|
||||
int snd_unregister_device(int type, struct snd_card *card, int dev)
|
||||
{
|
||||
int cardnum, minor;
|
||||
struct snd_minor *mptr;
|
||||
int minor;
|
||||
|
||||
cardnum = card ? card->number : -1;
|
||||
mutex_lock(&sound_mutex);
|
||||
for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor)
|
||||
if ((mptr = snd_minors[minor]) != NULL &&
|
||||
mptr->type == type &&
|
||||
mptr->card == cardnum &&
|
||||
mptr->device == dev)
|
||||
break;
|
||||
if (minor == ARRAY_SIZE(snd_minors)) {
|
||||
minor = find_snd_minor(type, card, dev);
|
||||
if (minor < 0) {
|
||||
mutex_unlock(&sound_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
class_device_destroy(sound_class, MKDEV(major, minor));
|
||||
|
||||
kfree(snd_minors[minor]);
|
||||
snd_minors[minor] = NULL;
|
||||
mutex_unlock(&sound_mutex);
|
||||
kfree(mptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_unregister_device);
|
||||
|
||||
int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev,
|
||||
const struct class_device_attribute *attr)
|
||||
{
|
||||
int minor, ret = -EINVAL;
|
||||
struct class_device *cdev;
|
||||
|
||||
mutex_lock(&sound_mutex);
|
||||
minor = find_snd_minor(type, card, dev);
|
||||
if (minor >= 0 && (cdev = snd_minors[minor]->class_dev) != NULL)
|
||||
ret = class_device_create_file(cdev, attr);
|
||||
mutex_unlock(&sound_mutex);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_add_device_sysfs_file);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/*
|
||||
* INFO PART
|
||||
|
|
Загрузка…
Ссылка в новой задаче