Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / drivers / staging / greybus / audio_manager_module.c
CommitLineData
8db00736
SA
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
8db00736
SA
84static ssize_t gb_audio_module_vid_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.vid);
89}
90
91static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute =
92 __ATTR(vid, 0664, gb_audio_module_vid_show, NULL);
93
94static ssize_t gb_audio_module_pid_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.pid);
99}
100
101static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute =
102 __ATTR(pid, 0664, gb_audio_module_pid_show, NULL);
103
d0af1bd5 104static ssize_t gb_audio_module_intf_id_show(
8db00736
SA
105 struct gb_audio_manager_module *module,
106 struct gb_audio_manager_module_attribute *attr, char *buf)
107{
d0af1bd5 108 return sprintf(buf, "%d", module->desc.intf_id);
8db00736
SA
109}
110
111static struct gb_audio_manager_module_attribute
d0af1bd5
PB
112 gb_audio_module_intf_id_attribute =
113 __ATTR(intf_id, 0664, gb_audio_module_intf_id_show, NULL);
8db00736 114
a9234bfd 115static ssize_t gb_audio_module_ip_devices_show(
8db00736
SA
116 struct gb_audio_manager_module *module,
117 struct gb_audio_manager_module_attribute *attr, char *buf)
118{
a9234bfd 119 return sprintf(buf, "0x%X", module->desc.ip_devices);
8db00736
SA
120}
121
122static struct gb_audio_manager_module_attribute
a9234bfd
VA
123 gb_audio_module_ip_devices_attribute =
124 __ATTR(ip_devices, 0664, gb_audio_module_ip_devices_show, NULL);
125
126static ssize_t gb_audio_module_op_devices_show(
127 struct gb_audio_manager_module *module,
128 struct gb_audio_manager_module_attribute *attr, char *buf)
129{
130 return sprintf(buf, "0x%X", module->desc.op_devices);
131}
132
133static struct gb_audio_manager_module_attribute
134 gb_audio_module_op_devices_attribute =
135 __ATTR(op_devices, 0664, gb_audio_module_op_devices_show, NULL);
8db00736
SA
136
137static struct attribute *gb_audio_module_default_attrs[] = {
138 &gb_audio_module_name_attribute.attr,
8db00736
SA
139 &gb_audio_module_vid_attribute.attr,
140 &gb_audio_module_pid_attribute.attr,
d0af1bd5 141 &gb_audio_module_intf_id_attribute.attr,
a9234bfd
VA
142 &gb_audio_module_ip_devices_attribute.attr,
143 &gb_audio_module_op_devices_attribute.attr,
8db00736
SA
144 NULL, /* need to NULL terminate the list of attributes */
145};
146
147static struct kobj_type gb_audio_module_type = {
148 .sysfs_ops = &gb_audio_module_sysfs_ops,
149 .release = gb_audio_module_release,
150 .default_attrs = gb_audio_module_default_attrs,
151};
152
153static void send_add_uevent(struct gb_audio_manager_module *module)
154{
155 char name_string[128];
8db00736
SA
156 char vid_string[64];
157 char pid_string[64];
d0af1bd5 158 char intf_id_string[64];
a9234bfd
VA
159 char ip_devices_string[64];
160 char op_devices_string[64];
8db00736
SA
161
162 char *envp[] = {
163 name_string,
8db00736
SA
164 vid_string,
165 pid_string,
d0af1bd5 166 intf_id_string,
a9234bfd
VA
167 ip_devices_string,
168 op_devices_string,
8db00736
SA
169 NULL
170 };
171
172 snprintf(name_string, 128, "NAME=%s", module->desc.name);
8db00736
SA
173 snprintf(vid_string, 64, "VID=%d", module->desc.vid);
174 snprintf(pid_string, 64, "PID=%d", module->desc.pid);
d0af1bd5 175 snprintf(intf_id_string, 64, "INTF_ID=%d", module->desc.intf_id);
a9234bfd
VA
176 snprintf(ip_devices_string, 64, "I/P DEVICES=0x%X",
177 module->desc.ip_devices);
178 snprintf(op_devices_string, 64, "O/P DEVICES=0x%X",
179 module->desc.op_devices);
8db00736
SA
180
181 kobject_uevent_env(&module->kobj, KOBJ_ADD, envp);
182}
183
184int gb_audio_manager_module_create(
185 struct gb_audio_manager_module **module,
186 struct kset *manager_kset,
187 int id, struct gb_audio_manager_module_descriptor *desc)
188{
189 int err;
190 struct gb_audio_manager_module *m;
191
192 m = kzalloc(sizeof(*m), GFP_ATOMIC);
193 if (!m)
194 return -ENOMEM;
195
196 /* Initialize the node */
197 INIT_LIST_HEAD(&m->list);
198
199 /* Set the module id */
200 m->id = id;
201
202 /* Copy the provided descriptor */
203 memcpy(&m->desc, desc, sizeof(*desc));
204
205 /* set the kset */
206 m->kobj.kset = manager_kset;
207
208 /*
209 * Initialize and add the kobject to the kernel. All the default files
210 * will be created here. As we have already specified a kset for this
211 * kobject, we don't have to set a parent for the kobject, the kobject
212 * will be placed beneath that kset automatically.
213 */
214 err = kobject_init_and_add(&m->kobj, &gb_audio_module_type, NULL, "%d",
215 id);
216 if (err) {
217 pr_err("failed initializing kobject for audio module #%d\n",
218 id);
219 kobject_put(&m->kobj);
220 return err;
221 }
222
223 /*
224 * Notify the object was created
225 */
226 send_add_uevent(m);
227
228 *module = m;
229 pr_info("Created audio module #%d\n", id);
230 return 0;
231}
232
233void gb_audio_manager_module_dump(struct gb_audio_manager_module *module)
234{
49b9137a 235 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",
8db00736
SA
236 module->id,
237 module->desc.name,
8db00736
SA
238 module->desc.vid,
239 module->desc.pid,
d0af1bd5 240 module->desc.intf_id,
a9234bfd
VA
241 module->desc.ip_devices,
242 module->desc.op_devices);
8db00736 243}