1
2
3
4
5
6
7
8#include <linux/slab.h>
9
10#include "audio_manager.h"
11#include "audio_manager_private.h"
12
13#define to_gb_audio_module_attr(x) \
14 container_of(x, struct gb_audio_manager_module_attribute, attr)
15#define to_gb_audio_module(x) \
16 container_of(x, struct gb_audio_manager_module, kobj)
17
18struct gb_audio_manager_module_attribute {
19 struct attribute attr;
20 ssize_t (*show)(struct gb_audio_manager_module *module,
21 struct gb_audio_manager_module_attribute *attr,
22 char *buf);
23 ssize_t (*store)(struct gb_audio_manager_module *module,
24 struct gb_audio_manager_module_attribute *attr,
25 const char *buf, size_t count);
26};
27
28static ssize_t gb_audio_module_attr_show(
29 struct kobject *kobj, struct attribute *attr, char *buf)
30{
31 struct gb_audio_manager_module_attribute *attribute;
32 struct gb_audio_manager_module *module;
33
34 attribute = to_gb_audio_module_attr(attr);
35 module = to_gb_audio_module(kobj);
36
37 if (!attribute->show)
38 return -EIO;
39
40 return attribute->show(module, attribute, buf);
41}
42
43static ssize_t gb_audio_module_attr_store(struct kobject *kobj,
44 struct attribute *attr,
45 const char *buf, size_t len)
46{
47 struct gb_audio_manager_module_attribute *attribute;
48 struct gb_audio_manager_module *module;
49
50 attribute = to_gb_audio_module_attr(attr);
51 module = to_gb_audio_module(kobj);
52
53 if (!attribute->store)
54 return -EIO;
55
56 return attribute->store(module, attribute, buf, len);
57}
58
59static const struct sysfs_ops gb_audio_module_sysfs_ops = {
60 .show = gb_audio_module_attr_show,
61 .store = gb_audio_module_attr_store,
62};
63
64static void gb_audio_module_release(struct kobject *kobj)
65{
66 struct gb_audio_manager_module *module = to_gb_audio_module(kobj);
67
68 pr_info("Destroying audio module #%d\n", module->id);
69
70 kfree(module);
71}
72
73static ssize_t gb_audio_module_name_show(
74 struct gb_audio_manager_module *module,
75 struct gb_audio_manager_module_attribute *attr, char *buf)
76{
77 return sprintf(buf, "%s", module->desc.name);
78}
79
80static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute =
81 __ATTR(name, 0664, gb_audio_module_name_show, NULL);
82
83static ssize_t gb_audio_module_vid_show(
84 struct gb_audio_manager_module *module,
85 struct gb_audio_manager_module_attribute *attr, char *buf)
86{
87 return sprintf(buf, "%d", module->desc.vid);
88}
89
90static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute =
91 __ATTR(vid, 0664, gb_audio_module_vid_show, NULL);
92
93static ssize_t gb_audio_module_pid_show(
94 struct gb_audio_manager_module *module,
95 struct gb_audio_manager_module_attribute *attr, char *buf)
96{
97 return sprintf(buf, "%d", module->desc.pid);
98}
99
100static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute =
101 __ATTR(pid, 0664, gb_audio_module_pid_show, NULL);
102
103static ssize_t gb_audio_module_intf_id_show(
104 struct gb_audio_manager_module *module,
105 struct gb_audio_manager_module_attribute *attr, char *buf)
106{
107 return sprintf(buf, "%d", module->desc.intf_id);
108}
109
110static struct gb_audio_manager_module_attribute
111 gb_audio_module_intf_id_attribute =
112 __ATTR(intf_id, 0664, gb_audio_module_intf_id_show, NULL);
113
114static ssize_t gb_audio_module_ip_devices_show(
115 struct gb_audio_manager_module *module,
116 struct gb_audio_manager_module_attribute *attr, char *buf)
117{
118 return sprintf(buf, "0x%X", module->desc.ip_devices);
119}
120
121static struct gb_audio_manager_module_attribute
122 gb_audio_module_ip_devices_attribute =
123 __ATTR(ip_devices, 0664, gb_audio_module_ip_devices_show, NULL);
124
125static ssize_t gb_audio_module_op_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.op_devices);
130}
131
132static struct gb_audio_manager_module_attribute
133 gb_audio_module_op_devices_attribute =
134 __ATTR(op_devices, 0664, gb_audio_module_op_devices_show, NULL);
135
136static struct attribute *gb_audio_module_default_attrs[] = {
137 &gb_audio_module_name_attribute.attr,
138 &gb_audio_module_vid_attribute.attr,
139 &gb_audio_module_pid_attribute.attr,
140 &gb_audio_module_intf_id_attribute.attr,
141 &gb_audio_module_ip_devices_attribute.attr,
142 &gb_audio_module_op_devices_attribute.attr,
143 NULL,
144};
145
146static struct kobj_type gb_audio_module_type = {
147 .sysfs_ops = &gb_audio_module_sysfs_ops,
148 .release = gb_audio_module_release,
149 .default_attrs = gb_audio_module_default_attrs,
150};
151
152static void send_add_uevent(struct gb_audio_manager_module *module)
153{
154 char name_string[128];
155 char vid_string[64];
156 char pid_string[64];
157 char intf_id_string[64];
158 char ip_devices_string[64];
159 char op_devices_string[64];
160
161 char *envp[] = {
162 name_string,
163 vid_string,
164 pid_string,
165 intf_id_string,
166 ip_devices_string,
167 op_devices_string,
168 NULL
169 };
170
171 snprintf(name_string, 128, "NAME=%s", module->desc.name);
172 snprintf(vid_string, 64, "VID=%d", module->desc.vid);
173 snprintf(pid_string, 64, "PID=%d", module->desc.pid);
174 snprintf(intf_id_string, 64, "INTF_ID=%d", module->desc.intf_id);
175 snprintf(ip_devices_string, 64, "I/P DEVICES=0x%X",
176 module->desc.ip_devices);
177 snprintf(op_devices_string, 64, "O/P DEVICES=0x%X",
178 module->desc.op_devices);
179
180 kobject_uevent_env(&module->kobj, KOBJ_ADD, envp);
181}
182
183int gb_audio_manager_module_create(
184 struct gb_audio_manager_module **module,
185 struct kset *manager_kset,
186 int id, struct gb_audio_manager_module_descriptor *desc)
187{
188 int err;
189 struct gb_audio_manager_module *m;
190
191 m = kzalloc(sizeof(*m), GFP_ATOMIC);
192 if (!m)
193 return -ENOMEM;
194
195
196 INIT_LIST_HEAD(&m->list);
197
198
199 m->id = id;
200
201
202 memcpy(&m->desc, desc, sizeof(*desc));
203
204
205 m->kobj.kset = manager_kset;
206
207
208
209
210
211
212
213 err = kobject_init_and_add(&m->kobj, &gb_audio_module_type, NULL, "%d",
214 id);
215 if (err) {
216 pr_err("failed initializing kobject for audio module #%d\n",
217 id);
218 kobject_put(&m->kobj);
219 return err;
220 }
221
222
223
224
225 send_add_uevent(m);
226
227 *module = m;
228 pr_info("Created audio module #%d\n", id);
229 return 0;
230}
231
232void gb_audio_manager_module_dump(struct gb_audio_manager_module *module)
233{
234 pr_info("audio module #%d name=%s vid=%d pid=%d intf_id=%d i/p devices=0x%X o/p devices=0x%X\n",
235 module->id,
236 module->desc.name,
237 module->desc.vid,
238 module->desc.pid,
239 module->desc.intf_id,
240 module->desc.ip_devices,
241 module->desc.op_devices);
242}
243