// SPDX-License-Identifier: GPL-2.0 /* * AVIRT - ALSA Virtual Soundcard * * Copyright (c) 2010-2018 Fiberdyne Systems Pty Ltd * * core.c - AVIRT core internals */ #include #include #include #include #include "core.h" MODULE_AUTHOR("James O'Shannessy "); MODULE_AUTHOR("Mark Farrugia "); MODULE_DESCRIPTION("ALSA virtual, dynamic soundcard"); MODULE_LICENSE("GPL v2"); #define D_LOGNAME "core" #define D_INFOK(fmt, args...) DINFO(D_LOGNAME, fmt, ##args) #define D_PRINTK(fmt, args...) DDEBUG(D_LOGNAME, fmt, ##args) #define D_ERRORK(fmt, args...) DERROR(D_LOGNAME, fmt, ##args) #define SND_AVIRTUAL_DRIVER "snd_avirt" static struct snd_avirt_core core = { .stream_count = 0, .streams_sealed = false, }; struct snd_avirt_coreinfo coreinfo = { .version = { 0, 0, 1 }, }; static LIST_HEAD(audiopath_list); struct snd_avirt_audiopath_obj { struct kobject kobj; struct list_head list; struct snd_avirt_audiopath *path; }; static struct kset *snd_avirt_audiopath_kset; static struct kobject *kobj; #define to_audiopath_obj(d) \ container_of(d, struct snd_avirt_audiopath_obj, kobj) #define to_audiopath_attr(a) \ container_of(a, struct snd_avirt_audiopath_attribute, attr) /** * struct snd_avirt_audiopath_attribute - access the attributes of Audio Path * @attr: attributes of an Audio Path * @show: pointer to the show function * @store: pointer to the store function */ struct snd_avirt_audiopath_attribute { struct attribute attr; ssize_t (*show)(struct snd_avirt_audiopath_obj *d, struct snd_avirt_audiopath_attribute *attr, char *buf); ssize_t (*store)(struct snd_avirt_audiopath_obj *d, struct snd_avirt_audiopath_attribute *attr, const char *buf, size_t count); }; /** * audiopath_attr_show - show function of an Audio Path * @kobj: pointer to kobject * @attr: pointer to attribute struct * @buf: buffer */ static ssize_t audiopath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct snd_avirt_audiopath_attribute *audiopath_attr; struct snd_avirt_audiopath_obj *audiopath_obj; audiopath_attr = to_audiopath_attr(attr); audiopath_obj = to_audiopath_obj(kobj); if (!audiopath_attr->show) return -EIO; return audiopath_attr->show(audiopath_obj, audiopath_attr, buf); } /** * audiopath_attr_store - attribute store function of Audio Path object * @kobj: pointer to kobject * @attr: pointer to attribute struct * @buf: buffer * @len: length of buffer */ static ssize_t audiopath_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len) { struct snd_avirt_audiopath_attribute *audiopath_attr; struct snd_avirt_audiopath_obj *audiopath_obj; audiopath_attr = to_audiopath_attr(attr); audiopath_obj = to_audiopath_obj(kobj); if (!audiopath_attr->store) return -EIO; return audiopath_attr->store(audiopath_obj, audiopath_attr, buf, len); } static const struct sysfs_ops snd_avirt_audiopath_sysfs_ops = { .show = audiopath_attr_show, .store = audiopath_attr_store, }; /** * snd_avirt_audiopath_release - Audio Path release function * @kobj: pointer to Audio Paths's kobject */ static void snd_avirt_audiopath_release(struct kobject *kobj) { struct snd_avirt_audiopath_obj *audiopath_obj = to_audiopath_obj(kobj); kfree(audiopath_obj); } static ssize_t audiopath_name_show(struct snd_avirt_audiopath_obj *audiopath_obj, struct snd_avirt_audiopath_attribute *attr, char *buf) { return sprintf(buf, "%s\n", audiopath_obj->path->name); } static ssize_t audiopath_version_show(struct snd_avirt_audiopath_obj *audiopath_obj, struct snd_avirt_audiopath_attribute *attr, char *buf) { struct snd_avirt_audiopath *audiopath = audiopath_obj->path; return sprintf(buf, "%d.%d.%d\n", audiopath->version[0], audiopath->version[1], audiopath->version[2]); } static struct snd_avirt_audiopath_attribute snd_avirt_audiopath_attrs[] = { __ATTR_RO(audiopath_name), __ATTR_RO(audiopath_version), }; static struct attribute *snd_avirt_audiopath_def_attrs[] = { &snd_avirt_audiopath_attrs[0].attr, &snd_avirt_audiopath_attrs[1].attr, NULL, }; static struct kobj_type snd_avirt_audiopath_ktype = { .sysfs_ops = &snd_avirt_audiopath_sysfs_ops, .release = snd_avirt_audiopath_release, .default_attrs = snd_avirt_audiopath_def_attrs, }; /** * create_snd_avirt_audiopath_obj - creates an Audio Path object * @uid: Unique ID of the Audio Path * * This creates an Audio Path object and assigns the kset and registers * it with sysfs. * @return: Pointer to the Audio Path object or NULL if it failed. */ static struct snd_avirt_audiopath_obj *