linux/drivers/staging/greybus/audio_manager_module.c
<<
>>
Prefs
   1/*
   2 * Greybus operations
   3 *
   4 * Copyright 2015-2016 Google Inc.
   5 *
   6 * Released under the GPLv2 only.
   7 */
   8
   9#include <linux/slab.h>
  10
  11#include "audio_manager.h"
  12#include "audio_manager_private.h"
  13
  14#define to_gb_audio_module_attr(x)      \
  15                container_of(x, struct gb_audio_manager_module_attribute, attr)
  16#define to_gb_audio_module(x)           \
  17                container_of(x, struct gb_audio_manager_module, kobj)
  18
  19struct gb_audio_manager_module_attribute {
  20        struct attribute attr;
  21        ssize_t (*show)(struct gb_audio_manager_module *module,
  22                        struct gb_audio_manager_module_attribute *attr,
  23                        char *buf);
  24        ssize_t (*store)(struct gb_audio_manager_module *module,
  25                         struct gb_audio_manager_module_attribute *attr,
  26                         const char *buf, size_t count);
  27};
  28
  29static ssize_t gb_audio_module_attr_show(
  30        struct kobject *kobj, struct attribute *attr, char *buf)
  31{
  32        struct gb_audio_manager_module_attribute *attribute;
  33        struct gb_audio_manager_module *module;
  34
  35        attribute = to_gb_audio_module_attr(attr);
  36        module = to_gb_audio_module(kobj);
  37
  38        if (!attribute->show)
  39                return -EIO;
  40
  41        return attribute->show(module, attribute, buf);
  42}
  43
  44static ssize_t gb_audio_module_attr_store(struct kobject *kobj,
  45                                          struct attribute *attr,
  46                                          const char *buf, size_t len)
  47{
  48        struct gb_audio_manager_module_attribute *attribute;
  49        struct gb_audio_manager_module *module;
  50
  51        attribute = to_gb_audio_module_attr(attr);
  52        module = to_gb_audio_module(kobj);
  53
  54        if (!attribute->store)
  55                return -EIO;
  56
  57        return attribute->store(module, attribute, buf, len);
  58}
  59
  60static const struct sysfs_ops gb_audio_module_sysfs_ops = {
  61        .show = gb_audio_module_attr_show,
  62        .store = gb_audio_module_attr_store,
  63};
  64
  65static void gb_audio_module_release(struct kobject *kobj)
  66{
  67        struct gb_audio_manager_module *module = to_gb_audio_module(kobj);
  68
  69        pr_info("Destroying audio module #%d\n", module->id);
  70        /* TODO -> delete from list */
  71        kfree(module);
  72}
  73
  74static ssize_t gb_audio_module_name_show(
  75        struct gb_audio_manager_module *module,
  76        struct gb_audio_manager_module_attribute *attr, char *buf)
  77{
  78        return sprintf(buf, "%s", module->desc.name);
  79}
  80
  81static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute =
  82        __ATTR(name, 0664, gb_audio_module_name_show, NULL);
  83
  84static ssize_t gb_audio_module_slot_show(
  85        struct gb_audio_manager_module *module,
  86        struct gb_audio_manager_module_attribute *attr, char *buf)
  87{
  88        return sprintf(buf, "%d", module->desc.slot);
  89}
  90
  91static struct gb_audio_manager_module_attribute gb_audio_module_slot_attribute =
  92        __ATTR(slot, 0664, gb_audio_module_slot_show, NULL);
  93
  94static ssize_t gb_audio_module_vid_show(
  95        struct gb_audio_manager_module *module,
  96        struct gb_audio_manager_module_attribute *attr, char *buf)
  97{
  98        return sprintf(buf, "%d", module->desc.vid);
  99}
 100
 101static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute =
 102        __ATTR(vid, 0664, gb_audio_module_vid_show, NULL);
 103
 104static ssize_t gb_audio_module_pid_show(
 105        struct gb_audio_manager_module *module,
 106        struct gb_audio_manager_module_attribute *attr, char *buf)
 107{
 108        return sprintf(buf, "%d", module->desc.pid);
 109}
 110
 111static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute =
 112        __ATTR(pid, 0664, gb_audio_module_pid_show, NULL);
 113
 114static ssize_t gb_audio_module_cport_show(
 115        struct gb_audio_manager_module *module,
 116        struct gb_audio_manager_module_attribute *attr, char *buf)
 117{
 118        return sprintf(buf, "%d", module->desc.cport);
 119}
 120
 121static struct gb_audio_manager_module_attribute
 122                                        gb_audio_module_cport_attribute =
 123        __ATTR(cport, 0664, gb_audio_module_cport_show, NULL);
 124
 125static ssize_t gb_audio_module_ip_devices_show(
 126        struct gb_audio_manager_module *module,
 127        struct gb_audio_manager_module_attribute *attr, char *buf)
 128{
 129        return sprintf(buf, "0x%X", module->desc.ip_devices);
 130}
 131
 132static struct gb_audio_manager_module_attribute
 133                                        gb_audio_module_ip_devices_attribute =
 134        __ATTR(ip_devices, 0664, gb_audio_module_ip_devices_show, NULL);
 135
 136static ssize_t gb_audio_module_op_devices_show(
 137        struct gb_audio_manager_module *module,
 138        struct gb_audio_manager_module_attribute *attr, char *buf)
 139{
 140        return sprintf(buf, "0x%X", module->desc.op_devices);
 141}
 142
 143static struct gb_audio_manager_module_attribute
 144                                        gb_audio_module_op_devices_attribute =
 145        __ATTR(op_devices, 0664, gb_audio_module_op_devices_show, NULL);
 146
 147static struct attribute *gb_audio_module_default_attrs[] = {
 148        &gb_audio_module_name_attribute.attr,
 149        &gb_audio_module_slot_attribute.attr,
 150        &gb_audio_module_vid_attribute.attr,
 151        &gb_audio_module_pid_attribute.attr,
 152        &gb_audio_module_cport_attribute.attr,
 153        &gb_audio_module_ip_devices_attribute.attr,
 154        &gb_audio_module_op_devices_attribute.attr,
 155        NULL,   /* need to NULL terminate the list of attributes */
 156};
 157
 158static struct kobj_type gb_audio_module_type = {
 159        .sysfs_ops = &gb_audio_module_sysfs_ops,
 160        .release = gb_audio_module_release,
 161        .default_attrs = gb_audio_module_default_attrs,
 162};
 163
 164static void send_add_uevent(struct gb_audio_manager_module *module)
 165{
 166        char name_string[128];
 167        char slot_string[64];
 168        char vid_string[64];
 169        char pid_string[64];
 170        char cport_string[64];
 171        char ip_devices_string[64];
 172        char op_devices_string[64];
 173
 174        char *envp[] = {
 175                name_string,
 176                slot_string,
 177                vid_string,
 178                pid_string,
 179                cport_string,
 180                ip_devices_string,
 181                op_devices_string,
 182                NULL
 183        };
 184
 185        snprintf(name_string, 128, "NAME=%s", module->desc.name);
 186        snprintf(slot_string, 64, "SLOT=%d", module->desc.slot);
 187        snprintf(vid_string, 64, "VID=%d", module->desc.vid);
 188        snprintf(pid_string, 64, "PID=%d", module->desc.pid);
 189        snprintf(cport_string, 64, "CPORT=%d", module->desc.cport);
 190        snprintf(ip_devices_string, 64, "I/P DEVICES=0x%X",
 191                 module->desc.ip_devices);
 192        snprintf(op_devices_string, 64, "O/P DEVICES=0x%X",
 193                 module->desc.op_devices);
 194
 195        kobject_uevent_env(&module->kobj, KOBJ_ADD, envp);
 196}
 197
 198int gb_audio_manager_module_create(
 199        struct gb_audio_manager_module **module,
 200        struct kset *manager_kset,
 201        int id, struct gb_audio_manager_module_descriptor *desc)
 202{
 203        int err;
 204        struct gb_audio_manager_module *m;
 205
 206        m = kzalloc(sizeof(*m), GFP_ATOMIC);
 207        if (!m)
 208                return -ENOMEM;
 209
 210        /* Initialize the node */
 211        INIT_LIST_HEAD(&m->list);
 212
 213        /* Set the module id */
 214        m->id = id;
 215
 216        /* Copy the provided descriptor */
 217        memcpy(&m->desc, desc, sizeof(*desc));
 218
 219        /* set the kset */
 220        m->kobj.kset = manager_kset;
 221
 222        /*
 223         * Initialize and add the kobject to the kernel.  All the default files
 224         * will be created here.  As we have already specified a kset for this
 225         * kobject, we don't have to set a parent for the kobject, the kobject
 226         * will be placed beneath that kset automatically.
 227         */
 228        err = kobject_init_and_add(&m->kobj, &gb_audio_module_type, NULL, "%d",
 229                                   id);
 230        if (err) {
 231                pr_err("failed initializing kobject for audio module #%d\n",
 232                       id);
 233                kobject_put(&m->kobj);
 234                return err;
 235        }
 236
 237        /*
 238         * Notify the object was created
 239         */
 240        send_add_uevent(m);
 241
 242        *module = m;
 243        pr_info("Created audio module #%d\n", id);
 244        return 0;
 245}
 246
 247void gb_audio_manager_module_dump(struct gb_audio_manager_module *module)
 248{
 249        pr_info("audio module #%d name=%s slot=%d vid=%d pid=%d cport=%d i/p devices=0x%X o/p devices=0x%X\n",
 250                module->id,
 251                module->desc.name,
 252                module->desc.slot,
 253                module->desc.vid,
 254                module->desc.pid,
 255                module->desc.cport,
 256                module->desc.ip_devices,
 257                module->desc.op_devices);
 258}
 259