diff options
author | Mark Farrugia <mark.farrugia@fiberdyne.com.au> | 2019-03-01 17:20:29 +1100 |
---|---|---|
committer | Mark Farrugia <mark.farrugia@fiberdyne.com.au> | 2019-03-01 17:20:29 +1100 |
commit | 763bbd2abc251d351746bfddfbac9d39a74e4492 (patch) | |
tree | f412bc93576ccddd26f3c52a2243e2d2cbbd5bac /sysfs.c | |
parent | 443bdab5db1cd5494e94aa7031c4a25e33a9c6bb (diff) |
Move sysfs functionality to sysfs.c
Signed-off-by: Mark Farrugia <mark.farrugia@fiberdyne.com.au>
Diffstat (limited to 'sysfs.c')
-rw-r--r-- | sysfs.c | 174 |
1 files changed, 174 insertions, 0 deletions
@@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AVIRT - ALSA Virtual Soundcard + * + * Copyright (c) 2010-2019 Fiberdyne Systems Pty Ltd + * + * configfs.c - AVIRT sysfs support + */ + +#include <linux/slab.h> + +#include "core.h" + +#define D_LOGNAME "sysfs" + +#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) + +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 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 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(name), + __ATTR_RO(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, +}; + +struct snd_avirt_audiopath_obj *snd_avirt_audiopath_create_obj(const char *uid) +{ + struct snd_avirt_audiopath_obj *snd_avirt_audiopath; + int retval; + + snd_avirt_audiopath = kzalloc(sizeof(*snd_avirt_audiopath), GFP_KERNEL); + if (!snd_avirt_audiopath) + return NULL; + snd_avirt_audiopath->kobj.kset = snd_avirt_audiopath_kset; + retval = kobject_init_and_add(&snd_avirt_audiopath->kobj, + &snd_avirt_audiopath_ktype, kobj, "%s", + uid); + if (retval) { + kobject_put(&snd_avirt_audiopath->kobj); + return NULL; + } + kobject_uevent(&snd_avirt_audiopath->kobj, KOBJ_ADD); + return snd_avirt_audiopath; +} + +void snd_avirt_audiopath_destroy_obj(struct snd_avirt_audiopath_obj *p) +{ + kobject_put(&p->kobj); +} + +int __init snd_avirt_sysfs_init(struct snd_avirt_core *core) +{ + snd_avirt_audiopath_kset = + kset_create_and_add("audiopaths", NULL, &core->dev->kobj); + if (!snd_avirt_audiopath_kset) + return -ENOMEM; + + return 0; +} + +void __exit snd_avirt_sysfs_exit(struct snd_avirt_core *core) +{ + kset_unregister(snd_avirt_audiopath_kset); +} |