Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / usb / gadget / function / uvc_configfs.c
1 /*
2  * uvc_configfs.c
3  *
4  * Configfs support for the uvc function.
5  *
6  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
7  *              http://www.samsung.com
8  *
9  * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15 #include "u_uvc.h"
16 #include "uvc_configfs.h"
17
18 #define UVCG_STREAMING_CONTROL_SIZE     1
19
20 #define CONFIGFS_ATTR_OPS_RO(_item)                                     \
21 static ssize_t _item##_attr_show(struct config_item *item,              \
22                                  struct configfs_attribute *attr,       \
23                                  char *page)                            \
24 {                                                                       \
25         struct _item *_item = to_##_item(item);                         \
26         struct _item##_attribute *_item##_attr =                        \
27                 container_of(attr, struct _item##_attribute, attr);     \
28         ssize_t ret = 0;                                                \
29                                                                         \
30         if (_item##_attr->show)                                         \
31                 ret = _item##_attr->show(_item, page);                  \
32         return ret;                                                     \
33 }
34
35 static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item);
36
37 /* control/header/<NAME> */
38 DECLARE_UVC_HEADER_DESCRIPTOR(1);
39
40 struct uvcg_control_header {
41         struct config_item              item;
42         struct UVC_HEADER_DESCRIPTOR(1) desc;
43         unsigned                        linked;
44 };
45
46 static struct uvcg_control_header *to_uvcg_control_header(struct config_item *item)
47 {
48         return container_of(item, struct uvcg_control_header, item);
49 }
50
51 CONFIGFS_ATTR_STRUCT(uvcg_control_header);
52 CONFIGFS_ATTR_OPS(uvcg_control_header);
53
54 static struct configfs_item_operations uvcg_control_header_item_ops = {
55         .show_attribute         = uvcg_control_header_attr_show,
56         .store_attribute        = uvcg_control_header_attr_store,
57 };
58
59 #define UVCG_CTRL_HDR_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \
60 static ssize_t uvcg_control_header_##cname##_show(                      \
61         struct uvcg_control_header *ch, char *page)                     \
62 {                                                                       \
63         struct f_uvc_opts *opts;                                        \
64         struct config_item *opts_item;                                  \
65         struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
66         int result;                                                     \
67                                                                         \
68         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
69                                                                         \
70         opts_item = ch->item.ci_parent->ci_parent->ci_parent;           \
71         opts = to_f_uvc_opts(opts_item);                                \
72                                                                         \
73         mutex_lock(&opts->lock);                                        \
74         result = sprintf(page, "%d\n", conv(ch->desc.aname));           \
75         mutex_unlock(&opts->lock);                                      \
76                                                                         \
77         mutex_unlock(su_mutex);                                         \
78         return result;                                                  \
79 }                                                                       \
80                                                                         \
81 static ssize_t                                                          \
82 uvcg_control_header_##cname##_store(struct uvcg_control_header *ch,     \
83                            const char *page, size_t len)                \
84 {                                                                       \
85         struct f_uvc_opts *opts;                                        \
86         struct config_item *opts_item;                                  \
87         struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
88         int ret;                                                        \
89         uxx num;                                                        \
90                                                                         \
91         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
92                                                                         \
93         opts_item = ch->item.ci_parent->ci_parent->ci_parent;           \
94         opts = to_f_uvc_opts(opts_item);                                \
95                                                                         \
96         mutex_lock(&opts->lock);                                        \
97         if (ch->linked || opts->refcnt) {                               \
98                 ret = -EBUSY;                                           \
99                 goto end;                                               \
100         }                                                               \
101                                                                         \
102         ret = str2u(page, 0, &num);                                     \
103         if (ret)                                                        \
104                 goto end;                                               \
105                                                                         \
106         if (num > limit) {                                              \
107                 ret = -EINVAL;                                          \
108                 goto end;                                               \
109         }                                                               \
110         ch->desc.aname = vnoc(num);                                     \
111         ret = len;                                                      \
112 end:                                                                    \
113         mutex_unlock(&opts->lock);                                      \
114         mutex_unlock(su_mutex);                                         \
115         return ret;                                                     \
116 }                                                                       \
117                                                                         \
118 static struct uvcg_control_header_attribute                             \
119         uvcg_control_header_##cname =                                   \
120         __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR,                       \
121                         uvcg_control_header_##cname##_show,             \
122                         uvcg_control_header_##cname##_store)
123
124 UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, le16_to_cpu, kstrtou16, u16, cpu_to_le16,
125                    0xffff);
126
127 UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, le32_to_cpu, kstrtou32,
128                    u32, cpu_to_le32, 0x7fffffff);
129
130 #undef UVCG_CTRL_HDR_ATTR
131
132 static struct configfs_attribute *uvcg_control_header_attrs[] = {
133         &uvcg_control_header_bcd_uvc.attr,
134         &uvcg_control_header_dw_clock_frequency.attr,
135         NULL,
136 };
137
138 static struct config_item_type uvcg_control_header_type = {
139         .ct_item_ops    = &uvcg_control_header_item_ops,
140         .ct_attrs       = uvcg_control_header_attrs,
141         .ct_owner       = THIS_MODULE,
142 };
143
144 static struct config_item *uvcg_control_header_make(struct config_group *group,
145                                                     const char *name)
146 {
147         struct uvcg_control_header *h;
148
149         h = kzalloc(sizeof(*h), GFP_KERNEL);
150         if (!h)
151                 return ERR_PTR(-ENOMEM);
152
153         h->desc.bLength                 = UVC_DT_HEADER_SIZE(1);
154         h->desc.bDescriptorType         = USB_DT_CS_INTERFACE;
155         h->desc.bDescriptorSubType      = UVC_VC_HEADER;
156         h->desc.bcdUVC                  = cpu_to_le16(0x0100);
157         h->desc.dwClockFrequency        = cpu_to_le32(48000000);
158
159         config_item_init_type_name(&h->item, name, &uvcg_control_header_type);
160
161         return &h->item;
162 }
163
164 static void uvcg_control_header_drop(struct config_group *group,
165                               struct config_item *item)
166 {
167         struct uvcg_control_header *h = to_uvcg_control_header(item);
168
169         kfree(h);
170 }
171
172 /* control/header */
173 static struct uvcg_control_header_grp {
174         struct config_group     group;
175 } uvcg_control_header_grp;
176
177 static struct configfs_group_operations uvcg_control_header_grp_ops = {
178         .make_item              = uvcg_control_header_make,
179         .drop_item              = uvcg_control_header_drop,
180 };
181
182 static struct config_item_type uvcg_control_header_grp_type = {
183         .ct_group_ops   = &uvcg_control_header_grp_ops,
184         .ct_owner       = THIS_MODULE,
185 };
186
187 /* control/processing/default */
188 static struct uvcg_default_processing {
189         struct config_group     group;
190 } uvcg_default_processing;
191
192 static inline struct uvcg_default_processing
193 *to_uvcg_default_processing(struct config_item *item)
194 {
195         return container_of(to_config_group(item),
196                             struct uvcg_default_processing, group);
197 }
198
199 CONFIGFS_ATTR_STRUCT(uvcg_default_processing);
200 CONFIGFS_ATTR_OPS_RO(uvcg_default_processing);
201
202 static struct configfs_item_operations uvcg_default_processing_item_ops = {
203         .show_attribute         = uvcg_default_processing_attr_show,
204 };
205
206 #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, conv)                \
207 static ssize_t uvcg_default_processing_##cname##_show(                  \
208         struct uvcg_default_processing *dp, char *page)                 \
209 {                                                                       \
210         struct f_uvc_opts *opts;                                        \
211         struct config_item *opts_item;                                  \
212         struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;        \
213         struct uvc_processing_unit_descriptor *pd;                      \
214         int result;                                                     \
215                                                                         \
216         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
217                                                                         \
218         opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent;  \
219         opts = to_f_uvc_opts(opts_item);                                \
220         pd = &opts->uvc_processing;                                     \
221                                                                         \
222         mutex_lock(&opts->lock);                                        \
223         result = sprintf(page, "%d\n", conv(pd->aname));                \
224         mutex_unlock(&opts->lock);                                      \
225                                                                         \
226         mutex_unlock(su_mutex);                                         \
227         return result;                                                  \
228 }                                                                       \
229                                                                         \
230 static struct uvcg_default_processing_attribute                         \
231         uvcg_default_processing_##cname =                               \
232         __CONFIGFS_ATTR_RO(aname, uvcg_default_processing_##cname##_show)
233
234 #define identity_conv(x) (x)
235
236 UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id, bUnitID, identity_conv);
237 UVCG_DEFAULT_PROCESSING_ATTR(b_source_id, bSourceID, identity_conv);
238 UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier, wMaxMultiplier, le16_to_cpu);
239 UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, identity_conv);
240
241 #undef identity_conv
242
243 #undef UVCG_DEFAULT_PROCESSING_ATTR
244
245 static ssize_t uvcg_default_processing_bm_controls_show(
246         struct uvcg_default_processing *dp, char *page)
247 {
248         struct f_uvc_opts *opts;
249         struct config_item *opts_item;
250         struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;
251         struct uvc_processing_unit_descriptor *pd;
252         int result, i;
253         char *pg = page;
254
255         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
256
257         opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent;
258         opts = to_f_uvc_opts(opts_item);
259         pd = &opts->uvc_processing;
260
261         mutex_lock(&opts->lock);
262         for (result = 0, i = 0; i < pd->bControlSize; ++i) {
263                 result += sprintf(pg, "%d\n", pd->bmControls[i]);
264                 pg = page + result;
265         }
266         mutex_unlock(&opts->lock);
267
268         mutex_unlock(su_mutex);
269
270         return result;
271 }
272
273 static struct uvcg_default_processing_attribute
274         uvcg_default_processing_bm_controls =
275         __CONFIGFS_ATTR_RO(bmControls,
276                 uvcg_default_processing_bm_controls_show);
277
278 static struct configfs_attribute *uvcg_default_processing_attrs[] = {
279         &uvcg_default_processing_b_unit_id.attr,
280         &uvcg_default_processing_b_source_id.attr,
281         &uvcg_default_processing_w_max_multiplier.attr,
282         &uvcg_default_processing_bm_controls.attr,
283         &uvcg_default_processing_i_processing.attr,
284         NULL,
285 };
286
287 static struct config_item_type uvcg_default_processing_type = {
288         .ct_item_ops    = &uvcg_default_processing_item_ops,
289         .ct_attrs       = uvcg_default_processing_attrs,
290         .ct_owner       = THIS_MODULE,
291 };
292
293 /* struct uvcg_processing {}; */
294
295 static struct config_group *uvcg_processing_default_groups[] = {
296         &uvcg_default_processing.group,
297         NULL,
298 };
299
300 /* control/processing */
301 static struct uvcg_processing_grp {
302         struct config_group     group;
303 } uvcg_processing_grp;
304
305 static struct config_item_type uvcg_processing_grp_type = {
306         .ct_owner = THIS_MODULE,
307 };
308
309 /* control/terminal/camera/default */
310 static struct uvcg_default_camera {
311         struct config_group     group;
312 } uvcg_default_camera;
313
314 static inline struct uvcg_default_camera
315 *to_uvcg_default_camera(struct config_item *item)
316 {
317         return container_of(to_config_group(item),
318                             struct uvcg_default_camera, group);
319 }
320
321 CONFIGFS_ATTR_STRUCT(uvcg_default_camera);
322 CONFIGFS_ATTR_OPS_RO(uvcg_default_camera);
323
324 static struct configfs_item_operations uvcg_default_camera_item_ops = {
325         .show_attribute         = uvcg_default_camera_attr_show,
326 };
327
328 #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, conv)                    \
329 static ssize_t uvcg_default_camera_##cname##_show(                      \
330         struct uvcg_default_camera *dc, char *page)                     \
331 {                                                                       \
332         struct f_uvc_opts *opts;                                        \
333         struct config_item *opts_item;                                  \
334         struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;        \
335         struct uvc_camera_terminal_descriptor *cd;                      \
336         int result;                                                     \
337                                                                         \
338         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
339                                                                         \
340         opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent-> \
341                         ci_parent;                                      \
342         opts = to_f_uvc_opts(opts_item);                                \
343         cd = &opts->uvc_camera_terminal;                                \
344                                                                         \
345         mutex_lock(&opts->lock);                                        \
346         result = sprintf(page, "%d\n", conv(cd->aname));                \
347         mutex_unlock(&opts->lock);                                      \
348                                                                         \
349         mutex_unlock(su_mutex);                                         \
350                                                                         \
351         return result;                                                  \
352 }                                                                       \
353                                                                         \
354 static struct uvcg_default_camera_attribute                             \
355         uvcg_default_camera_##cname =                                   \
356         __CONFIGFS_ATTR_RO(aname, uvcg_default_camera_##cname##_show)
357
358 #define identity_conv(x) (x)
359
360 UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id, bTerminalID, identity_conv);
361 UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type, wTerminalType, le16_to_cpu);
362 UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv);
363 UVCG_DEFAULT_CAMERA_ATTR(i_terminal, iTerminal, identity_conv);
364 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min, wObjectiveFocalLengthMin,
365                          le16_to_cpu);
366 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax,
367                          le16_to_cpu);
368 UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength,
369                          le16_to_cpu);
370
371 #undef identity_conv
372
373 #undef UVCG_DEFAULT_CAMERA_ATTR
374
375 static ssize_t uvcg_default_camera_bm_controls_show(
376         struct uvcg_default_camera *dc, char *page)
377 {
378         struct f_uvc_opts *opts;
379         struct config_item *opts_item;
380         struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;
381         struct uvc_camera_terminal_descriptor *cd;
382         int result, i;
383         char *pg = page;
384
385         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
386
387         opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent->
388                         ci_parent;
389         opts = to_f_uvc_opts(opts_item);
390         cd = &opts->uvc_camera_terminal;
391
392         mutex_lock(&opts->lock);
393         for (result = 0, i = 0; i < cd->bControlSize; ++i) {
394                 result += sprintf(pg, "%d\n", cd->bmControls[i]);
395                 pg = page + result;
396         }
397         mutex_unlock(&opts->lock);
398
399         mutex_unlock(su_mutex);
400         return result;
401 }
402
403 static struct uvcg_default_camera_attribute
404         uvcg_default_camera_bm_controls =
405         __CONFIGFS_ATTR_RO(bmControls, uvcg_default_camera_bm_controls_show);
406
407 static struct configfs_attribute *uvcg_default_camera_attrs[] = {
408         &uvcg_default_camera_b_terminal_id.attr,
409         &uvcg_default_camera_w_terminal_type.attr,
410         &uvcg_default_camera_b_assoc_terminal.attr,
411         &uvcg_default_camera_i_terminal.attr,
412         &uvcg_default_camera_w_objective_focal_length_min.attr,
413         &uvcg_default_camera_w_objective_focal_length_max.attr,
414         &uvcg_default_camera_w_ocular_focal_length.attr,
415         &uvcg_default_camera_bm_controls.attr,
416         NULL,
417 };
418
419 static struct config_item_type uvcg_default_camera_type = {
420         .ct_item_ops    = &uvcg_default_camera_item_ops,
421         .ct_attrs       = uvcg_default_camera_attrs,
422         .ct_owner       = THIS_MODULE,
423 };
424
425 /* struct uvcg_camera {}; */
426
427 static struct config_group *uvcg_camera_default_groups[] = {
428         &uvcg_default_camera.group,
429         NULL,
430 };
431
432 /* control/terminal/camera */
433 static struct uvcg_camera_grp {
434         struct config_group     group;
435 } uvcg_camera_grp;
436
437 static struct config_item_type uvcg_camera_grp_type = {
438         .ct_owner = THIS_MODULE,
439 };
440
441 /* control/terminal/output/default */
442 static struct uvcg_default_output {
443         struct config_group     group;
444 } uvcg_default_output;
445
446 static inline struct uvcg_default_output
447 *to_uvcg_default_output(struct config_item *item)
448 {
449         return container_of(to_config_group(item),
450                             struct uvcg_default_output, group);
451 }
452
453 CONFIGFS_ATTR_STRUCT(uvcg_default_output);
454 CONFIGFS_ATTR_OPS_RO(uvcg_default_output);
455
456 static struct configfs_item_operations uvcg_default_output_item_ops = {
457         .show_attribute         = uvcg_default_output_attr_show,
458 };
459
460 #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, conv)                    \
461 static ssize_t uvcg_default_output_##cname##_show(                      \
462         struct uvcg_default_output *dout, char *page)                   \
463 {                                                                       \
464         struct f_uvc_opts *opts;                                        \
465         struct config_item *opts_item;                                  \
466         struct mutex *su_mutex = &dout->group.cg_subsys->su_mutex;      \
467         struct uvc_output_terminal_descriptor *cd;                      \
468         int result;                                                     \
469                                                                         \
470         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
471                                                                         \
472         opts_item = dout->group.cg_item.ci_parent->ci_parent->          \
473                         ci_parent->ci_parent;                           \
474         opts = to_f_uvc_opts(opts_item);                                \
475         cd = &opts->uvc_output_terminal;                                \
476                                                                         \
477         mutex_lock(&opts->lock);                                        \
478         result = sprintf(page, "%d\n", conv(cd->aname));                \
479         mutex_unlock(&opts->lock);                                      \
480                                                                         \
481         mutex_unlock(su_mutex);                                         \
482                                                                         \
483         return result;                                                  \
484 }                                                                       \
485                                                                         \
486 static struct uvcg_default_output_attribute                             \
487         uvcg_default_output_##cname =                                   \
488         __CONFIGFS_ATTR_RO(aname, uvcg_default_output_##cname##_show)
489
490 #define identity_conv(x) (x)
491
492 UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, identity_conv);
493 UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, le16_to_cpu);
494 UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv);
495 UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, identity_conv);
496 UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, identity_conv);
497
498 #undef identity_conv
499
500 #undef UVCG_DEFAULT_OUTPUT_ATTR
501
502 static struct configfs_attribute *uvcg_default_output_attrs[] = {
503         &uvcg_default_output_b_terminal_id.attr,
504         &uvcg_default_output_w_terminal_type.attr,
505         &uvcg_default_output_b_assoc_terminal.attr,
506         &uvcg_default_output_b_source_id.attr,
507         &uvcg_default_output_i_terminal.attr,
508         NULL,
509 };
510
511 static struct config_item_type uvcg_default_output_type = {
512         .ct_item_ops    = &uvcg_default_output_item_ops,
513         .ct_attrs       = uvcg_default_output_attrs,
514         .ct_owner       = THIS_MODULE,
515 };
516
517 /* struct uvcg_output {}; */
518
519 static struct config_group *uvcg_output_default_groups[] = {
520         &uvcg_default_output.group,
521         NULL,
522 };
523
524 /* control/terminal/output */
525 static struct uvcg_output_grp {
526         struct config_group     group;
527 } uvcg_output_grp;
528
529 static struct config_item_type uvcg_output_grp_type = {
530         .ct_owner = THIS_MODULE,
531 };
532
533 static struct config_group *uvcg_terminal_default_groups[] = {
534         &uvcg_camera_grp.group,
535         &uvcg_output_grp.group,
536         NULL,
537 };
538
539 /* control/terminal */
540 static struct uvcg_terminal_grp {
541         struct config_group     group;
542 } uvcg_terminal_grp;
543
544 static struct config_item_type uvcg_terminal_grp_type = {
545         .ct_owner = THIS_MODULE,
546 };
547
548 /* control/class/{fs} */
549 static struct uvcg_control_class {
550         struct config_group     group;
551 } uvcg_control_class_fs, uvcg_control_class_ss;
552
553
554 static inline struct uvc_descriptor_header
555 **uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o)
556 {
557         struct uvcg_control_class *cl = container_of(to_config_group(i),
558                 struct uvcg_control_class, group);
559
560         if (cl == &uvcg_control_class_fs)
561                 return o->uvc_fs_control_cls;
562
563         if (cl == &uvcg_control_class_ss)
564                 return o->uvc_ss_control_cls;
565
566         return NULL;
567 }
568
569 static int uvcg_control_class_allow_link(struct config_item *src,
570                                          struct config_item *target)
571 {
572         struct config_item *control, *header;
573         struct f_uvc_opts *opts;
574         struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
575         struct uvc_descriptor_header **class_array;
576         struct uvcg_control_header *target_hdr;
577         int ret = -EINVAL;
578
579         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
580
581         control = src->ci_parent->ci_parent;
582         header = config_group_find_item(to_config_group(control), "header");
583         if (!header || target->ci_parent != header)
584                 goto out;
585
586         opts = to_f_uvc_opts(control->ci_parent);
587
588         mutex_lock(&opts->lock);
589
590         class_array = uvcg_get_ctl_class_arr(src, opts);
591         if (!class_array)
592                 goto unlock;
593         if (opts->refcnt || class_array[0]) {
594                 ret = -EBUSY;
595                 goto unlock;
596         }
597
598         target_hdr = to_uvcg_control_header(target);
599         ++target_hdr->linked;
600         class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc;
601         ret = 0;
602
603 unlock:
604         mutex_unlock(&opts->lock);
605 out:
606         mutex_unlock(su_mutex);
607         return ret;
608 }
609
610 static int uvcg_control_class_drop_link(struct config_item *src,
611                                         struct config_item *target)
612 {
613         struct config_item *control, *header;
614         struct f_uvc_opts *opts;
615         struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
616         struct uvc_descriptor_header **class_array;
617         struct uvcg_control_header *target_hdr;
618         int ret = -EINVAL;
619
620         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
621
622         control = src->ci_parent->ci_parent;
623         header = config_group_find_item(to_config_group(control), "header");
624         if (!header || target->ci_parent != header)
625                 goto out;
626
627         opts = to_f_uvc_opts(control->ci_parent);
628
629         mutex_lock(&opts->lock);
630
631         class_array = uvcg_get_ctl_class_arr(src, opts);
632         if (!class_array)
633                 goto unlock;
634         if (opts->refcnt) {
635                 ret = -EBUSY;
636                 goto unlock;
637         }
638
639         target_hdr = to_uvcg_control_header(target);
640         --target_hdr->linked;
641         class_array[0] = NULL;
642         ret = 0;
643
644 unlock:
645         mutex_unlock(&opts->lock);
646 out:
647         mutex_unlock(su_mutex);
648         return ret;
649 }
650
651 static struct configfs_item_operations uvcg_control_class_item_ops = {
652         .allow_link     = uvcg_control_class_allow_link,
653         .drop_link      = uvcg_control_class_drop_link,
654 };
655
656 static struct config_item_type uvcg_control_class_type = {
657         .ct_item_ops    = &uvcg_control_class_item_ops,
658         .ct_owner       = THIS_MODULE,
659 };
660
661 static struct config_group *uvcg_control_class_default_groups[] = {
662         &uvcg_control_class_fs.group,
663         &uvcg_control_class_ss.group,
664         NULL,
665 };
666
667 /* control/class */
668 static struct uvcg_control_class_grp {
669         struct config_group     group;
670 } uvcg_control_class_grp;
671
672 static struct config_item_type uvcg_control_class_grp_type = {
673         .ct_owner = THIS_MODULE,
674 };
675
676 static struct config_group *uvcg_control_default_groups[] = {
677         &uvcg_control_header_grp.group,
678         &uvcg_processing_grp.group,
679         &uvcg_terminal_grp.group,
680         &uvcg_control_class_grp.group,
681         NULL,
682 };
683
684 /* control */
685 static struct uvcg_control_grp {
686         struct config_group     group;
687 } uvcg_control_grp;
688
689 static struct config_item_type uvcg_control_grp_type = {
690         .ct_owner = THIS_MODULE,
691 };
692
693 /* streaming/uncompressed */
694 static struct uvcg_uncompressed_grp {
695         struct config_group     group;
696 } uvcg_uncompressed_grp;
697
698 /* streaming/mjpeg */
699 static struct uvcg_mjpeg_grp {
700         struct config_group     group;
701 } uvcg_mjpeg_grp;
702
703 static struct config_item *fmt_parent[] = {
704         &uvcg_uncompressed_grp.group.cg_item,
705         &uvcg_mjpeg_grp.group.cg_item,
706 };
707
708 enum uvcg_format_type {
709         UVCG_UNCOMPRESSED = 0,
710         UVCG_MJPEG,
711 };
712
713 struct uvcg_format {
714         struct config_group     group;
715         enum uvcg_format_type   type;
716         unsigned                linked;
717         unsigned                num_frames;
718         __u8                    bmaControls[UVCG_STREAMING_CONTROL_SIZE];
719 };
720
721 static struct uvcg_format *to_uvcg_format(struct config_item *item)
722 {
723         return container_of(to_config_group(item), struct uvcg_format, group);
724 }
725
726 static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page)
727 {
728         struct f_uvc_opts *opts;
729         struct config_item *opts_item;
730         struct mutex *su_mutex = &f->group.cg_subsys->su_mutex;
731         int result, i;
732         char *pg = page;
733
734         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
735
736         opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent;
737         opts = to_f_uvc_opts(opts_item);
738
739         mutex_lock(&opts->lock);
740         result = sprintf(pg, "0x");
741         pg += result;
742         for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) {
743                 result += sprintf(pg, "%x\n", f->bmaControls[i]);
744                 pg = page + result;
745         }
746         mutex_unlock(&opts->lock);
747
748         mutex_unlock(su_mutex);
749         return result;
750 }
751
752 static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch,
753                                               const char *page, size_t len)
754 {
755         struct f_uvc_opts *opts;
756         struct config_item *opts_item;
757         struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex;
758         int ret = -EINVAL;
759
760         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
761
762         opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent;
763         opts = to_f_uvc_opts(opts_item);
764
765         mutex_lock(&opts->lock);
766         if (ch->linked || opts->refcnt) {
767                 ret = -EBUSY;
768                 goto end;
769         }
770
771         if (len < 4 || *page != '0' ||
772             (*(page + 1) != 'x' && *(page + 1) != 'X'))
773                 goto end;
774         ret = hex2bin(ch->bmaControls, page + 2, 1);
775         if (ret < 0)
776                 goto end;
777         ret = len;
778 end:
779         mutex_unlock(&opts->lock);
780         mutex_unlock(su_mutex);
781         return ret;
782 }
783
784 struct uvcg_format_ptr {
785         struct uvcg_format      *fmt;
786         struct list_head        entry;
787 };
788
789 /* streaming/header/<NAME> */
790 struct uvcg_streaming_header {
791         struct config_item                              item;
792         struct uvc_input_header_descriptor              desc;
793         unsigned                                        linked;
794         struct list_head                                formats;
795         unsigned                                        num_fmt;
796 };
797
798 static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item *item)
799 {
800         return container_of(item, struct uvcg_streaming_header, item);
801 }
802
803 CONFIGFS_ATTR_STRUCT(uvcg_streaming_header);
804 CONFIGFS_ATTR_OPS(uvcg_streaming_header);
805
806 static int uvcg_streaming_header_allow_link(struct config_item *src,
807                                             struct config_item *target)
808 {
809         struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
810         struct config_item *opts_item;
811         struct f_uvc_opts *opts;
812         struct uvcg_streaming_header *src_hdr;
813         struct uvcg_format *target_fmt = NULL;
814         struct uvcg_format_ptr *format_ptr;
815         int i, ret = -EINVAL;
816
817         src_hdr = to_uvcg_streaming_header(src);
818         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
819
820         opts_item = src->ci_parent->ci_parent->ci_parent;
821         opts = to_f_uvc_opts(opts_item);
822
823         mutex_lock(&opts->lock);
824
825         if (src_hdr->linked) {
826                 ret = -EBUSY;
827                 goto out;
828         }
829
830         for (i = 0; i < ARRAY_SIZE(fmt_parent); ++i)
831                 if (target->ci_parent == fmt_parent[i])
832                         break;
833         if (i == ARRAY_SIZE(fmt_parent))
834                 goto out;
835
836         target_fmt = container_of(to_config_group(target), struct uvcg_format,
837                                   group);
838         if (!target_fmt)
839                 goto out;
840
841         format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL);
842         if (!format_ptr) {
843                 ret = -ENOMEM;
844                 goto out;
845         }
846         ret = 0;
847         format_ptr->fmt = target_fmt;
848         list_add_tail(&format_ptr->entry, &src_hdr->formats);
849         ++src_hdr->num_fmt;
850
851 out:
852         mutex_unlock(&opts->lock);
853         mutex_unlock(su_mutex);
854         return ret;
855 }
856
857 static int uvcg_streaming_header_drop_link(struct config_item *src,
858                                            struct config_item *target)
859 {
860         struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
861         struct config_item *opts_item;
862         struct f_uvc_opts *opts;
863         struct uvcg_streaming_header *src_hdr;
864         struct uvcg_format *target_fmt = NULL;
865         struct uvcg_format_ptr *format_ptr, *tmp;
866         int ret = -EINVAL;
867
868         src_hdr = to_uvcg_streaming_header(src);
869         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
870
871         opts_item = src->ci_parent->ci_parent->ci_parent;
872         opts = to_f_uvc_opts(opts_item);
873
874         mutex_lock(&opts->lock);
875         target_fmt = container_of(to_config_group(target), struct uvcg_format,
876                                   group);
877         if (!target_fmt)
878                 goto out;
879
880         list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry)
881                 if (format_ptr->fmt == target_fmt) {
882                         list_del(&format_ptr->entry);
883                         kfree(format_ptr);
884                         --src_hdr->num_fmt;
885                         break;
886                 }
887
888 out:
889         mutex_unlock(&opts->lock);
890         mutex_unlock(su_mutex);
891         return ret;
892
893 }
894
895 static struct configfs_item_operations uvcg_streaming_header_item_ops = {
896         .show_attribute         = uvcg_streaming_header_attr_show,
897         .store_attribute        = uvcg_streaming_header_attr_store,
898         .allow_link             = uvcg_streaming_header_allow_link,
899         .drop_link              = uvcg_streaming_header_drop_link,
900 };
901
902 #define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv)                  \
903 static ssize_t uvcg_streaming_header_##cname##_show(                    \
904         struct uvcg_streaming_header *sh, char *page)                   \
905 {                                                                       \
906         struct f_uvc_opts *opts;                                        \
907         struct config_item *opts_item;                                  \
908         struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\
909         int result;                                                     \
910                                                                         \
911         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
912                                                                         \
913         opts_item = sh->item.ci_parent->ci_parent->ci_parent;           \
914         opts = to_f_uvc_opts(opts_item);                                \
915                                                                         \
916         mutex_lock(&opts->lock);                                        \
917         result = sprintf(page, "%d\n", conv(sh->desc.aname));           \
918         mutex_unlock(&opts->lock);                                      \
919                                                                         \
920         mutex_unlock(su_mutex);                                         \
921         return result;                                                  \
922 }                                                                       \
923                                                                         \
924 static struct uvcg_streaming_header_attribute                           \
925         uvcg_streaming_header_##cname =                                 \
926         __CONFIGFS_ATTR_RO(aname, uvcg_streaming_header_##cname##_show)
927
928 #define identity_conv(x) (x)
929
930 UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, identity_conv);
931 UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, identity_conv);
932 UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod,
933                            identity_conv);
934 UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, identity_conv);
935 UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv);
936
937 #undef identity_conv
938
939 #undef UVCG_STREAMING_HEADER_ATTR
940
941 static struct configfs_attribute *uvcg_streaming_header_attrs[] = {
942         &uvcg_streaming_header_bm_info.attr,
943         &uvcg_streaming_header_b_terminal_link.attr,
944         &uvcg_streaming_header_b_still_capture_method.attr,
945         &uvcg_streaming_header_b_trigger_support.attr,
946         &uvcg_streaming_header_b_trigger_usage.attr,
947         NULL,
948 };
949
950 static struct config_item_type uvcg_streaming_header_type = {
951         .ct_item_ops    = &uvcg_streaming_header_item_ops,
952         .ct_attrs       = uvcg_streaming_header_attrs,
953         .ct_owner       = THIS_MODULE,
954 };
955
956 static struct config_item
957 *uvcg_streaming_header_make(struct config_group *group, const char *name)
958 {
959         struct uvcg_streaming_header *h;
960
961         h = kzalloc(sizeof(*h), GFP_KERNEL);
962         if (!h)
963                 return ERR_PTR(-ENOMEM);
964
965         INIT_LIST_HEAD(&h->formats);
966         h->desc.bDescriptorType         = USB_DT_CS_INTERFACE;
967         h->desc.bDescriptorSubType      = UVC_VS_INPUT_HEADER;
968         h->desc.bTerminalLink           = 3;
969         h->desc.bControlSize            = UVCG_STREAMING_CONTROL_SIZE;
970
971         config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type);
972
973         return &h->item;
974 }
975
976 static void uvcg_streaming_header_drop(struct config_group *group,
977                               struct config_item *item)
978 {
979         struct uvcg_streaming_header *h = to_uvcg_streaming_header(item);
980
981         kfree(h);
982 }
983
984 /* streaming/header */
985 static struct uvcg_streaming_header_grp {
986         struct config_group     group;
987 } uvcg_streaming_header_grp;
988
989 static struct configfs_group_operations uvcg_streaming_header_grp_ops = {
990         .make_item              = uvcg_streaming_header_make,
991         .drop_item              = uvcg_streaming_header_drop,
992 };
993
994 static struct config_item_type uvcg_streaming_header_grp_type = {
995         .ct_group_ops   = &uvcg_streaming_header_grp_ops,
996         .ct_owner       = THIS_MODULE,
997 };
998
999 /* streaming/<mode>/<format>/<NAME> */
1000 struct uvcg_frame {
1001         struct {
1002                 u8      b_length;
1003                 u8      b_descriptor_type;
1004                 u8      b_descriptor_subtype;
1005                 u8      b_frame_index;
1006                 u8      bm_capabilities;
1007                 u16     w_width;
1008                 u16     w_height;
1009                 u32     dw_min_bit_rate;
1010                 u32     dw_max_bit_rate;
1011                 u32     dw_max_video_frame_buffer_size;
1012                 u32     dw_default_frame_interval;
1013                 u8      b_frame_interval_type;
1014         } __attribute__((packed)) frame;
1015         u32 *dw_frame_interval;
1016         enum uvcg_format_type   fmt_type;
1017         struct config_item      item;
1018 };
1019
1020 static struct uvcg_frame *to_uvcg_frame(struct config_item *item)
1021 {
1022         return container_of(item, struct uvcg_frame, item);
1023 }
1024
1025 CONFIGFS_ATTR_STRUCT(uvcg_frame);
1026 CONFIGFS_ATTR_OPS(uvcg_frame);
1027
1028 static struct configfs_item_operations uvcg_frame_item_ops = {
1029         .show_attribute         = uvcg_frame_attr_show,
1030         .store_attribute        = uvcg_frame_attr_store,
1031 };
1032
1033 #define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \
1034 static ssize_t uvcg_frame_##cname##_show(struct uvcg_frame *f, char *page)\
1035 {                                                                       \
1036         struct f_uvc_opts *opts;                                        \
1037         struct config_item *opts_item;                                  \
1038         struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1039         int result;                                                     \
1040                                                                         \
1041         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1042                                                                         \
1043         opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \
1044         opts = to_f_uvc_opts(opts_item);                                \
1045                                                                         \
1046         mutex_lock(&opts->lock);                                        \
1047         result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname));  \
1048         mutex_unlock(&opts->lock);                                      \
1049                                                                         \
1050         mutex_unlock(su_mutex);                                         \
1051         return result;                                                  \
1052 }                                                                       \
1053                                                                         \
1054 static ssize_t  uvcg_frame_##cname##_store(struct uvcg_frame *f,        \
1055                                            const char *page, size_t len)\
1056 {                                                                       \
1057         struct f_uvc_opts *opts;                                        \
1058         struct config_item *opts_item;                                  \
1059         struct uvcg_format *fmt;                                        \
1060         struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1061         int ret;                                                        \
1062         u##bits num;                                                    \
1063                                                                         \
1064         ret = kstrtou##bits(page, 0, &num);                             \
1065         if (ret)                                                        \
1066                 return ret;                                             \
1067                                                                         \
1068         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1069                                                                         \
1070         opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \
1071         opts = to_f_uvc_opts(opts_item);                                \
1072         fmt = to_uvcg_format(f->item.ci_parent);                        \
1073                                                                         \
1074         mutex_lock(&opts->lock);                                        \
1075         if (fmt->linked || opts->refcnt) {                              \
1076                 ret = -EBUSY;                                           \
1077                 goto end;                                               \
1078         }                                                               \
1079                                                                         \
1080         f->frame.cname = to_little_endian(num);                         \
1081         ret = len;                                                      \
1082 end:                                                                    \
1083         mutex_unlock(&opts->lock);                                      \
1084         mutex_unlock(su_mutex);                                         \
1085         return ret;                                                     \
1086 }                                                                       \
1087                                                                         \
1088 static struct uvcg_frame_attribute                                      \
1089         uvcg_frame_##cname =                                            \
1090         __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR,                       \
1091                         uvcg_frame_##cname##_show,                      \
1092                         uvcg_frame_##cname##_store)
1093
1094 #define noop_conversion(x) (x)
1095
1096 UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion,
1097                 noop_conversion, 8);
1098 UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16);
1099 UVCG_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16);
1100 UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32);
1101 UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32);
1102 UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize,
1103                 le32_to_cpu, cpu_to_le32, 32);
1104 UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval,
1105                 le32_to_cpu, cpu_to_le32, 32);
1106
1107 #undef noop_conversion
1108
1109 #undef UVCG_FRAME_ATTR
1110
1111 static ssize_t uvcg_frame_dw_frame_interval_show(struct uvcg_frame *frm,
1112                                                  char *page)
1113 {
1114         struct f_uvc_opts *opts;
1115         struct config_item *opts_item;
1116         struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex;
1117         int result, i;
1118         char *pg = page;
1119
1120         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1121
1122         opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent;
1123         opts = to_f_uvc_opts(opts_item);
1124
1125         mutex_lock(&opts->lock);
1126         for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) {
1127                 result += sprintf(pg, "%d\n",
1128                                   le32_to_cpu(frm->dw_frame_interval[i]));
1129                 pg = page + result;
1130         }
1131         mutex_unlock(&opts->lock);
1132
1133         mutex_unlock(su_mutex);
1134         return result;
1135 }
1136
1137 static inline int __uvcg_count_frm_intrv(char *buf, void *priv)
1138 {
1139         ++*((int *)priv);
1140         return 0;
1141 }
1142
1143 static inline int __uvcg_fill_frm_intrv(char *buf, void *priv)
1144 {
1145         u32 num, **interv;
1146         int ret;
1147
1148         ret = kstrtou32(buf, 0, &num);
1149         if (ret)
1150                 return ret;
1151
1152         interv = priv;
1153         **interv = cpu_to_le32(num);
1154         ++*interv;
1155
1156         return 0;
1157 }
1158
1159 static int __uvcg_iter_frm_intrv(const char *page, size_t len,
1160                                  int (*fun)(char *, void *), void *priv)
1161 {
1162         /* sign, base 2 representation, newline, terminator */
1163         char buf[1 + sizeof(u32) * 8 + 1 + 1];
1164         const char *pg = page;
1165         int i, ret;
1166
1167         if (!fun)
1168                 return -EINVAL;
1169
1170         while (pg - page < len) {
1171                 i = 0;
1172                 while (i < sizeof(buf) && (pg - page < len) &&
1173                                 *pg != '\0' && *pg != '\n')
1174                         buf[i++] = *pg++;
1175                 if (i == sizeof(buf))
1176                         return -EINVAL;
1177                 while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
1178                         ++pg;
1179                 buf[i] = '\0';
1180                 ret = fun(buf, priv);
1181                 if (ret)
1182                         return ret;
1183         }
1184
1185         return 0;
1186 }
1187
1188 static ssize_t uvcg_frame_dw_frame_interval_store(struct uvcg_frame *ch,
1189                                                   const char *page, size_t len)
1190 {
1191         struct f_uvc_opts *opts;
1192         struct config_item *opts_item;
1193         struct uvcg_format *fmt;
1194         struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;
1195         int ret = 0, n = 0;
1196         u32 *frm_intrv, *tmp;
1197
1198         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1199
1200         opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent;
1201         opts = to_f_uvc_opts(opts_item);
1202         fmt = to_uvcg_format(ch->item.ci_parent);
1203
1204         mutex_lock(&opts->lock);
1205         if (fmt->linked || opts->refcnt) {
1206                 ret = -EBUSY;
1207                 goto end;
1208         }
1209
1210         ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n);
1211         if (ret)
1212                 goto end;
1213
1214         tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL);
1215         if (!frm_intrv) {
1216                 ret = -ENOMEM;
1217                 goto end;
1218         }
1219
1220         ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp);
1221         if (ret) {
1222                 kfree(frm_intrv);
1223                 goto end;
1224         }
1225
1226         kfree(ch->dw_frame_interval);
1227         ch->dw_frame_interval = frm_intrv;
1228         ch->frame.b_frame_interval_type = n;
1229         ret = len;
1230
1231 end:
1232         mutex_unlock(&opts->lock);
1233         mutex_unlock(su_mutex);
1234         return ret;
1235 }
1236
1237 static struct uvcg_frame_attribute
1238         uvcg_frame_dw_frame_interval =
1239         __CONFIGFS_ATTR(dwFrameInterval, S_IRUGO | S_IWUSR,
1240                         uvcg_frame_dw_frame_interval_show,
1241                         uvcg_frame_dw_frame_interval_store);
1242
1243 static struct configfs_attribute *uvcg_frame_attrs[] = {
1244         &uvcg_frame_bm_capabilities.attr,
1245         &uvcg_frame_w_width.attr,
1246         &uvcg_frame_w_height.attr,
1247         &uvcg_frame_dw_min_bit_rate.attr,
1248         &uvcg_frame_dw_max_bit_rate.attr,
1249         &uvcg_frame_dw_max_video_frame_buffer_size.attr,
1250         &uvcg_frame_dw_default_frame_interval.attr,
1251         &uvcg_frame_dw_frame_interval.attr,
1252         NULL,
1253 };
1254
1255 static struct config_item_type uvcg_frame_type = {
1256         .ct_item_ops    = &uvcg_frame_item_ops,
1257         .ct_attrs       = uvcg_frame_attrs,
1258         .ct_owner       = THIS_MODULE,
1259 };
1260
1261 static struct config_item *uvcg_frame_make(struct config_group *group,
1262                                            const char *name)
1263 {
1264         struct uvcg_frame *h;
1265         struct uvcg_format *fmt;
1266         struct f_uvc_opts *opts;
1267         struct config_item *opts_item;
1268
1269         h = kzalloc(sizeof(*h), GFP_KERNEL);
1270         if (!h)
1271                 return ERR_PTR(-ENOMEM);
1272
1273         h->frame.b_descriptor_type              = USB_DT_CS_INTERFACE;
1274         h->frame.b_frame_index                  = 1;
1275         h->frame.w_width                        = cpu_to_le16(640);
1276         h->frame.w_height                       = cpu_to_le16(360);
1277         h->frame.dw_min_bit_rate                = cpu_to_le32(18432000);
1278         h->frame.dw_max_bit_rate                = cpu_to_le32(55296000);
1279         h->frame.dw_max_video_frame_buffer_size = cpu_to_le32(460800);
1280         h->frame.dw_default_frame_interval      = cpu_to_le32(666666);
1281
1282         opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
1283         opts = to_f_uvc_opts(opts_item);
1284
1285         mutex_lock(&opts->lock);
1286         fmt = to_uvcg_format(&group->cg_item);
1287         if (fmt->type == UVCG_UNCOMPRESSED) {
1288                 h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED;
1289                 h->fmt_type = UVCG_UNCOMPRESSED;
1290         } else if (fmt->type == UVCG_MJPEG) {
1291                 h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
1292                 h->fmt_type = UVCG_MJPEG;
1293         } else {
1294                 mutex_unlock(&opts->lock);
1295                 kfree(h);
1296                 return ERR_PTR(-EINVAL);
1297         }
1298         ++fmt->num_frames;
1299         mutex_unlock(&opts->lock);
1300
1301         config_item_init_type_name(&h->item, name, &uvcg_frame_type);
1302
1303         return &h->item;
1304 }
1305
1306 static void uvcg_frame_drop(struct config_group *group, struct config_item *item)
1307 {
1308         struct uvcg_frame *h = to_uvcg_frame(item);
1309         struct uvcg_format *fmt;
1310         struct f_uvc_opts *opts;
1311         struct config_item *opts_item;
1312
1313         opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
1314         opts = to_f_uvc_opts(opts_item);
1315
1316         mutex_lock(&opts->lock);
1317         fmt = to_uvcg_format(&group->cg_item);
1318         --fmt->num_frames;
1319         kfree(h);
1320         mutex_unlock(&opts->lock);
1321 }
1322
1323 /* streaming/uncompressed/<NAME> */
1324 struct uvcg_uncompressed {
1325         struct uvcg_format              fmt;
1326         struct uvc_format_uncompressed  desc;
1327 };
1328
1329 static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item)
1330 {
1331         return container_of(
1332                 container_of(to_config_group(item), struct uvcg_format, group),
1333                 struct uvcg_uncompressed, fmt);
1334 }
1335
1336 CONFIGFS_ATTR_STRUCT(uvcg_uncompressed);
1337 CONFIGFS_ATTR_OPS(uvcg_uncompressed);
1338
1339 static struct configfs_item_operations uvcg_uncompressed_item_ops = {
1340         .show_attribute         = uvcg_uncompressed_attr_show,
1341         .store_attribute        = uvcg_uncompressed_attr_store,
1342 };
1343
1344 static struct configfs_group_operations uvcg_uncompressed_group_ops = {
1345         .make_item              = uvcg_frame_make,
1346         .drop_item              = uvcg_frame_drop,
1347 };
1348
1349 static ssize_t uvcg_uncompressed_guid_format_show(struct uvcg_uncompressed *ch,
1350                                                         char *page)
1351 {
1352         struct f_uvc_opts *opts;
1353         struct config_item *opts_item;
1354         struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
1355
1356         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1357
1358         opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
1359         opts = to_f_uvc_opts(opts_item);
1360
1361         mutex_lock(&opts->lock);
1362         memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
1363         mutex_unlock(&opts->lock);
1364
1365         mutex_unlock(su_mutex);
1366
1367         return sizeof(ch->desc.guidFormat);
1368 }
1369
1370 static ssize_t uvcg_uncompressed_guid_format_store(struct uvcg_uncompressed *ch,
1371                                                    const char *page, size_t len)
1372 {
1373         struct f_uvc_opts *opts;
1374         struct config_item *opts_item;
1375         struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
1376         int ret;
1377
1378         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1379
1380         opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
1381         opts = to_f_uvc_opts(opts_item);
1382
1383         mutex_lock(&opts->lock);
1384         if (ch->fmt.linked || opts->refcnt) {
1385                 ret = -EBUSY;
1386                 goto end;
1387         }
1388
1389         memcpy(ch->desc.guidFormat, page,
1390                min(sizeof(ch->desc.guidFormat), len));
1391         ret = sizeof(ch->desc.guidFormat);
1392
1393 end:
1394         mutex_unlock(&opts->lock);
1395         mutex_unlock(su_mutex);
1396         return ret;
1397 }
1398
1399 static struct uvcg_uncompressed_attribute uvcg_uncompressed_guid_format =
1400         __CONFIGFS_ATTR(guidFormat, S_IRUGO | S_IWUSR,
1401                         uvcg_uncompressed_guid_format_show,
1402                         uvcg_uncompressed_guid_format_store);
1403
1404
1405 #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv)                   \
1406 static ssize_t uvcg_uncompressed_##cname##_show(                        \
1407         struct uvcg_uncompressed *u, char *page)                        \
1408 {                                                                       \
1409         struct f_uvc_opts *opts;                                        \
1410         struct config_item *opts_item;                                  \
1411         struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
1412         int result;                                                     \
1413                                                                         \
1414         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1415                                                                         \
1416         opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1417         opts = to_f_uvc_opts(opts_item);                                \
1418                                                                         \
1419         mutex_lock(&opts->lock);                                        \
1420         result = sprintf(page, "%d\n", conv(u->desc.aname));            \
1421         mutex_unlock(&opts->lock);                                      \
1422                                                                         \
1423         mutex_unlock(su_mutex);                                         \
1424         return result;                                                  \
1425 }                                                                       \
1426                                                                         \
1427 static struct uvcg_uncompressed_attribute                               \
1428         uvcg_uncompressed_##cname =                                     \
1429         __CONFIGFS_ATTR_RO(aname, uvcg_uncompressed_##cname##_show)
1430
1431 #define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv)                      \
1432 static ssize_t uvcg_uncompressed_##cname##_show(                        \
1433         struct uvcg_uncompressed *u, char *page)                        \
1434 {                                                                       \
1435         struct f_uvc_opts *opts;                                        \
1436         struct config_item *opts_item;                                  \
1437         struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
1438         int result;                                                     \
1439                                                                         \
1440         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1441                                                                         \
1442         opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1443         opts = to_f_uvc_opts(opts_item);                                \
1444                                                                         \
1445         mutex_lock(&opts->lock);                                        \
1446         result = sprintf(page, "%d\n", conv(u->desc.aname));            \
1447         mutex_unlock(&opts->lock);                                      \
1448                                                                         \
1449         mutex_unlock(su_mutex);                                         \
1450         return result;                                                  \
1451 }                                                                       \
1452                                                                         \
1453 static ssize_t                                                          \
1454 uvcg_uncompressed_##cname##_store(struct uvcg_uncompressed *u,          \
1455                                     const char *page, size_t len)       \
1456 {                                                                       \
1457         struct f_uvc_opts *opts;                                        \
1458         struct config_item *opts_item;                                  \
1459         struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
1460         int ret;                                                        \
1461         u8 num;                                                         \
1462                                                                         \
1463         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1464                                                                         \
1465         opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1466         opts = to_f_uvc_opts(opts_item);                                \
1467                                                                         \
1468         mutex_lock(&opts->lock);                                        \
1469         if (u->fmt.linked || opts->refcnt) {                            \
1470                 ret = -EBUSY;                                           \
1471                 goto end;                                               \
1472         }                                                               \
1473                                                                         \
1474         ret = kstrtou8(page, 0, &num);                                  \
1475         if (ret)                                                        \
1476                 goto end;                                               \
1477                                                                         \
1478         if (num > 255) {                                                \
1479                 ret = -EINVAL;                                          \
1480                 goto end;                                               \
1481         }                                                               \
1482         u->desc.aname = num;                                            \
1483         ret = len;                                                      \
1484 end:                                                                    \
1485         mutex_unlock(&opts->lock);                                      \
1486         mutex_unlock(su_mutex);                                         \
1487         return ret;                                                     \
1488 }                                                                       \
1489                                                                         \
1490 static struct uvcg_uncompressed_attribute                               \
1491         uvcg_uncompressed_##cname =                                     \
1492         __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR,                       \
1493                         uvcg_uncompressed_##cname##_show,               \
1494                         uvcg_uncompressed_##cname##_store)
1495
1496 #define identity_conv(x) (x)
1497
1498 UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, identity_conv);
1499 UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex,
1500                        identity_conv);
1501 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
1502 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
1503 UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
1504
1505 #undef identity_conv
1506
1507 #undef UVCG_UNCOMPRESSED_ATTR
1508 #undef UVCG_UNCOMPRESSED_ATTR_RO
1509
1510 static inline ssize_t
1511 uvcg_uncompressed_bma_controls_show(struct uvcg_uncompressed *unc, char *page)
1512 {
1513         return uvcg_format_bma_controls_show(&unc->fmt, page);
1514 }
1515
1516 static inline ssize_t
1517 uvcg_uncompressed_bma_controls_store(struct uvcg_uncompressed *ch,
1518                                      const char *page, size_t len)
1519 {
1520         return uvcg_format_bma_controls_store(&ch->fmt, page, len);
1521 }
1522
1523 static struct uvcg_uncompressed_attribute uvcg_uncompressed_bma_controls =
1524         __CONFIGFS_ATTR(bmaControls, S_IRUGO | S_IWUSR,
1525                         uvcg_uncompressed_bma_controls_show,
1526                         uvcg_uncompressed_bma_controls_store);
1527
1528 static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
1529         &uvcg_uncompressed_guid_format.attr,
1530         &uvcg_uncompressed_b_bits_per_pixel.attr,
1531         &uvcg_uncompressed_b_default_frame_index.attr,
1532         &uvcg_uncompressed_b_aspect_ratio_x.attr,
1533         &uvcg_uncompressed_b_aspect_ratio_y.attr,
1534         &uvcg_uncompressed_bm_interface_flags.attr,
1535         &uvcg_uncompressed_bma_controls.attr,
1536         NULL,
1537 };
1538
1539 static struct config_item_type uvcg_uncompressed_type = {
1540         .ct_item_ops    = &uvcg_uncompressed_item_ops,
1541         .ct_group_ops   = &uvcg_uncompressed_group_ops,
1542         .ct_attrs       = uvcg_uncompressed_attrs,
1543         .ct_owner       = THIS_MODULE,
1544 };
1545
1546 static struct config_group *uvcg_uncompressed_make(struct config_group *group,
1547                                                    const char *name)
1548 {
1549         static char guid[] = {
1550                 'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
1551                  0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
1552         };
1553         struct uvcg_uncompressed *h;
1554
1555         h = kzalloc(sizeof(*h), GFP_KERNEL);
1556         if (!h)
1557                 return ERR_PTR(-ENOMEM);
1558
1559         h->desc.bLength                 = UVC_DT_FORMAT_UNCOMPRESSED_SIZE;
1560         h->desc.bDescriptorType         = USB_DT_CS_INTERFACE;
1561         h->desc.bDescriptorSubType      = UVC_VS_FORMAT_UNCOMPRESSED;
1562         memcpy(h->desc.guidFormat, guid, sizeof(guid));
1563         h->desc.bBitsPerPixel           = 16;
1564         h->desc.bDefaultFrameIndex      = 1;
1565         h->desc.bAspectRatioX           = 0;
1566         h->desc.bAspectRatioY           = 0;
1567         h->desc.bmInterfaceFlags        = 0;
1568         h->desc.bCopyProtect            = 0;
1569
1570         h->fmt.type = UVCG_UNCOMPRESSED;
1571         config_group_init_type_name(&h->fmt.group, name,
1572                                     &uvcg_uncompressed_type);
1573
1574         return &h->fmt.group;
1575 }
1576
1577 static void uvcg_uncompressed_drop(struct config_group *group,
1578                             struct config_item *item)
1579 {
1580         struct uvcg_uncompressed *h = to_uvcg_uncompressed(item);
1581
1582         kfree(h);
1583 }
1584
1585 static struct configfs_group_operations uvcg_uncompressed_grp_ops = {
1586         .make_group             = uvcg_uncompressed_make,
1587         .drop_item              = uvcg_uncompressed_drop,
1588 };
1589
1590 static struct config_item_type uvcg_uncompressed_grp_type = {
1591         .ct_group_ops   = &uvcg_uncompressed_grp_ops,
1592         .ct_owner       = THIS_MODULE,
1593 };
1594
1595 /* streaming/mjpeg/<NAME> */
1596 struct uvcg_mjpeg {
1597         struct uvcg_format              fmt;
1598         struct uvc_format_mjpeg         desc;
1599 };
1600
1601 static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item)
1602 {
1603         return container_of(
1604                 container_of(to_config_group(item), struct uvcg_format, group),
1605                 struct uvcg_mjpeg, fmt);
1606 }
1607
1608 CONFIGFS_ATTR_STRUCT(uvcg_mjpeg);
1609 CONFIGFS_ATTR_OPS(uvcg_mjpeg);
1610
1611 static struct configfs_item_operations uvcg_mjpeg_item_ops = {
1612         .show_attribute         = uvcg_mjpeg_attr_show,
1613         .store_attribute        = uvcg_mjpeg_attr_store,
1614 };
1615
1616 static struct configfs_group_operations uvcg_mjpeg_group_ops = {
1617         .make_item              = uvcg_frame_make,
1618         .drop_item              = uvcg_frame_drop,
1619 };
1620
1621 #define UVCG_MJPEG_ATTR_RO(cname, aname, conv)                          \
1622 static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\
1623 {                                                                       \
1624         struct f_uvc_opts *opts;                                        \
1625         struct config_item *opts_item;                                  \
1626         struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
1627         int result;                                                     \
1628                                                                         \
1629         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1630                                                                         \
1631         opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1632         opts = to_f_uvc_opts(opts_item);                                \
1633                                                                         \
1634         mutex_lock(&opts->lock);                                        \
1635         result = sprintf(page, "%d\n", conv(u->desc.aname));            \
1636         mutex_unlock(&opts->lock);                                      \
1637                                                                         \
1638         mutex_unlock(su_mutex);                                         \
1639         return result;                                                  \
1640 }                                                                       \
1641                                                                         \
1642 static struct uvcg_mjpeg_attribute                                      \
1643         uvcg_mjpeg_##cname =                                            \
1644         __CONFIGFS_ATTR_RO(aname, uvcg_mjpeg_##cname##_show)
1645
1646 #define UVCG_MJPEG_ATTR(cname, aname, conv)                             \
1647 static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\
1648 {                                                                       \
1649         struct f_uvc_opts *opts;                                        \
1650         struct config_item *opts_item;                                  \
1651         struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
1652         int result;                                                     \
1653                                                                         \
1654         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1655                                                                         \
1656         opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1657         opts = to_f_uvc_opts(opts_item);                                \
1658                                                                         \
1659         mutex_lock(&opts->lock);                                        \
1660         result = sprintf(page, "%d\n", conv(u->desc.aname));            \
1661         mutex_unlock(&opts->lock);                                      \
1662                                                                         \
1663         mutex_unlock(su_mutex);                                         \
1664         return result;                                                  \
1665 }                                                                       \
1666                                                                         \
1667 static ssize_t                                                          \
1668 uvcg_mjpeg_##cname##_store(struct uvcg_mjpeg *u,                        \
1669                            const char *page, size_t len)                \
1670 {                                                                       \
1671         struct f_uvc_opts *opts;                                        \
1672         struct config_item *opts_item;                                  \
1673         struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;     \
1674         int ret;                                                        \
1675         u8 num;                                                         \
1676                                                                         \
1677         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1678                                                                         \
1679         opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1680         opts = to_f_uvc_opts(opts_item);                                \
1681                                                                         \
1682         mutex_lock(&opts->lock);                                        \
1683         if (u->fmt.linked || opts->refcnt) {                            \
1684                 ret = -EBUSY;                                           \
1685                 goto end;                                               \
1686         }                                                               \
1687                                                                         \
1688         ret = kstrtou8(page, 0, &num);                                  \
1689         if (ret)                                                        \
1690                 goto end;                                               \
1691                                                                         \
1692         if (num > 255) {                                                \
1693                 ret = -EINVAL;                                          \
1694                 goto end;                                               \
1695         }                                                               \
1696         u->desc.aname = num;                                            \
1697         ret = len;                                                      \
1698 end:                                                                    \
1699         mutex_unlock(&opts->lock);                                      \
1700         mutex_unlock(su_mutex);                                         \
1701         return ret;                                                     \
1702 }                                                                       \
1703                                                                         \
1704 static struct uvcg_mjpeg_attribute                                      \
1705         uvcg_mjpeg_##cname =                                            \
1706         __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR,                       \
1707                         uvcg_mjpeg_##cname##_show,                      \
1708                         uvcg_mjpeg_##cname##_store)
1709
1710 #define identity_conv(x) (x)
1711
1712 UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex,
1713                        identity_conv);
1714 UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, identity_conv);
1715 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
1716 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
1717 UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
1718
1719 #undef identity_conv
1720
1721 #undef UVCG_MJPEG_ATTR
1722 #undef UVCG_MJPEG_ATTR_RO
1723
1724 static inline ssize_t
1725 uvcg_mjpeg_bma_controls_show(struct uvcg_mjpeg *unc, char *page)
1726 {
1727         return uvcg_format_bma_controls_show(&unc->fmt, page);
1728 }
1729
1730 static inline ssize_t
1731 uvcg_mjpeg_bma_controls_store(struct uvcg_mjpeg *ch,
1732                                      const char *page, size_t len)
1733 {
1734         return uvcg_format_bma_controls_store(&ch->fmt, page, len);
1735 }
1736
1737 static struct uvcg_mjpeg_attribute uvcg_mjpeg_bma_controls =
1738         __CONFIGFS_ATTR(bmaControls, S_IRUGO | S_IWUSR,
1739                         uvcg_mjpeg_bma_controls_show,
1740                         uvcg_mjpeg_bma_controls_store);
1741
1742 static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
1743         &uvcg_mjpeg_b_default_frame_index.attr,
1744         &uvcg_mjpeg_bm_flags.attr,
1745         &uvcg_mjpeg_b_aspect_ratio_x.attr,
1746         &uvcg_mjpeg_b_aspect_ratio_y.attr,
1747         &uvcg_mjpeg_bm_interface_flags.attr,
1748         &uvcg_mjpeg_bma_controls.attr,
1749         NULL,
1750 };
1751
1752 static struct config_item_type uvcg_mjpeg_type = {
1753         .ct_item_ops    = &uvcg_mjpeg_item_ops,
1754         .ct_group_ops   = &uvcg_mjpeg_group_ops,
1755         .ct_attrs       = uvcg_mjpeg_attrs,
1756         .ct_owner       = THIS_MODULE,
1757 };
1758
1759 static struct config_group *uvcg_mjpeg_make(struct config_group *group,
1760                                                    const char *name)
1761 {
1762         struct uvcg_mjpeg *h;
1763
1764         h = kzalloc(sizeof(*h), GFP_KERNEL);
1765         if (!h)
1766                 return ERR_PTR(-ENOMEM);
1767
1768         h->desc.bLength                 = UVC_DT_FORMAT_MJPEG_SIZE;
1769         h->desc.bDescriptorType         = USB_DT_CS_INTERFACE;
1770         h->desc.bDescriptorSubType      = UVC_VS_FORMAT_MJPEG;
1771         h->desc.bDefaultFrameIndex      = 1;
1772         h->desc.bAspectRatioX           = 0;
1773         h->desc.bAspectRatioY           = 0;
1774         h->desc.bmInterfaceFlags        = 0;
1775         h->desc.bCopyProtect            = 0;
1776
1777         h->fmt.type = UVCG_MJPEG;
1778         config_group_init_type_name(&h->fmt.group, name,
1779                                     &uvcg_mjpeg_type);
1780
1781         return &h->fmt.group;
1782 }
1783
1784 static void uvcg_mjpeg_drop(struct config_group *group,
1785                             struct config_item *item)
1786 {
1787         struct uvcg_mjpeg *h = to_uvcg_mjpeg(item);
1788
1789         kfree(h);
1790 }
1791
1792 static struct configfs_group_operations uvcg_mjpeg_grp_ops = {
1793         .make_group             = uvcg_mjpeg_make,
1794         .drop_item              = uvcg_mjpeg_drop,
1795 };
1796
1797 static struct config_item_type uvcg_mjpeg_grp_type = {
1798         .ct_group_ops   = &uvcg_mjpeg_grp_ops,
1799         .ct_owner       = THIS_MODULE,
1800 };
1801
1802 /* streaming/color_matching/default */
1803 static struct uvcg_default_color_matching {
1804         struct config_group     group;
1805 } uvcg_default_color_matching;
1806
1807 static inline struct uvcg_default_color_matching
1808 *to_uvcg_default_color_matching(struct config_item *item)
1809 {
1810         return container_of(to_config_group(item),
1811                             struct uvcg_default_color_matching, group);
1812 }
1813
1814 CONFIGFS_ATTR_STRUCT(uvcg_default_color_matching);
1815 CONFIGFS_ATTR_OPS_RO(uvcg_default_color_matching);
1816
1817 static struct configfs_item_operations uvcg_default_color_matching_item_ops = {
1818         .show_attribute         = uvcg_default_color_matching_attr_show,
1819 };
1820
1821 #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv)            \
1822 static ssize_t uvcg_default_color_matching_##cname##_show(              \
1823         struct uvcg_default_color_matching *dc, char *page)             \
1824 {                                                                       \
1825         struct f_uvc_opts *opts;                                        \
1826         struct config_item *opts_item;                                  \
1827         struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;        \
1828         struct uvc_color_matching_descriptor *cd;                       \
1829         int result;                                                     \
1830                                                                         \
1831         mutex_lock(su_mutex); /* for navigating configfs hierarchy */   \
1832                                                                         \
1833         opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent;  \
1834         opts = to_f_uvc_opts(opts_item);                                \
1835         cd = &opts->uvc_color_matching;                                 \
1836                                                                         \
1837         mutex_lock(&opts->lock);                                        \
1838         result = sprintf(page, "%d\n", conv(cd->aname));                \
1839         mutex_unlock(&opts->lock);                                      \
1840                                                                         \
1841         mutex_unlock(su_mutex);                                         \
1842         return result;                                                  \
1843 }                                                                       \
1844                                                                         \
1845 static struct uvcg_default_color_matching_attribute                     \
1846         uvcg_default_color_matching_##cname =                           \
1847         __CONFIGFS_ATTR_RO(aname, uvcg_default_color_matching_##cname##_show)
1848
1849 #define identity_conv(x) (x)
1850
1851 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries,
1852                                  identity_conv);
1853 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics,
1854                                  bTransferCharacteristics, identity_conv);
1855 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients,
1856                                  identity_conv);
1857
1858 #undef identity_conv
1859
1860 #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR
1861
1862 static struct configfs_attribute *uvcg_default_color_matching_attrs[] = {
1863         &uvcg_default_color_matching_b_color_primaries.attr,
1864         &uvcg_default_color_matching_b_transfer_characteristics.attr,
1865         &uvcg_default_color_matching_b_matrix_coefficients.attr,
1866         NULL,
1867 };
1868
1869 static struct config_item_type uvcg_default_color_matching_type = {
1870         .ct_item_ops    = &uvcg_default_color_matching_item_ops,
1871         .ct_attrs       = uvcg_default_color_matching_attrs,
1872         .ct_owner       = THIS_MODULE,
1873 };
1874
1875 /* struct uvcg_color_matching {}; */
1876
1877 static struct config_group *uvcg_color_matching_default_groups[] = {
1878         &uvcg_default_color_matching.group,
1879         NULL,
1880 };
1881
1882 /* streaming/color_matching */
1883 static struct uvcg_color_matching_grp {
1884         struct config_group     group;
1885 } uvcg_color_matching_grp;
1886
1887 static struct config_item_type uvcg_color_matching_grp_type = {
1888         .ct_owner = THIS_MODULE,
1889 };
1890
1891 /* streaming/class/{fs|hs|ss} */
1892 static struct uvcg_streaming_class {
1893         struct config_group     group;
1894 } uvcg_streaming_class_fs, uvcg_streaming_class_hs, uvcg_streaming_class_ss;
1895
1896
1897 static inline struct uvc_descriptor_header
1898 ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o)
1899 {
1900         struct uvcg_streaming_class *cl = container_of(to_config_group(i),
1901                 struct uvcg_streaming_class, group);
1902
1903         if (cl == &uvcg_streaming_class_fs)
1904                 return &o->uvc_fs_streaming_cls;
1905
1906         if (cl == &uvcg_streaming_class_hs)
1907                 return &o->uvc_hs_streaming_cls;
1908
1909         if (cl == &uvcg_streaming_class_ss)
1910                 return &o->uvc_ss_streaming_cls;
1911
1912         return NULL;
1913 }
1914
1915 enum uvcg_strm_type {
1916         UVCG_HEADER = 0,
1917         UVCG_FORMAT,
1918         UVCG_FRAME
1919 };
1920
1921 /*
1922  * Iterate over a hierarchy of streaming descriptors' config items.
1923  * The items are created by the user with configfs.
1924  *
1925  * It "processes" the header pointed to by @priv1, then for each format
1926  * that follows the header "processes" the format itself and then for
1927  * each frame inside a format "processes" the frame.
1928  *
1929  * As a "processing" function the @fun is used.
1930  *
1931  * __uvcg_iter_strm_cls() is used in two context: first, to calculate
1932  * the amount of memory needed for an array of streaming descriptors
1933  * and second, to actually fill the array.
1934  *
1935  * @h: streaming header pointer
1936  * @priv2: an "inout" parameter (the caller might want to see the changes to it)
1937  * @priv3: an "inout" parameter (the caller might want to see the changes to it)
1938  * @fun: callback function for processing each level of the hierarchy
1939  */
1940 static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
1941         void *priv2, void *priv3,
1942         int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type))
1943 {
1944         struct uvcg_format_ptr *f;
1945         struct config_group *grp;
1946         struct config_item *item;
1947         struct uvcg_frame *frm;
1948         int ret, i, j;
1949
1950         if (!fun)
1951                 return -EINVAL;
1952
1953         i = j = 0;
1954         ret = fun(h, priv2, priv3, 0, UVCG_HEADER);
1955         if (ret)
1956                 return ret;
1957         list_for_each_entry(f, &h->formats, entry) {
1958                 ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT);
1959                 if (ret)
1960                         return ret;
1961                 grp = &f->fmt->group;
1962                 list_for_each_entry(item, &grp->cg_children, ci_entry) {
1963                         frm = to_uvcg_frame(item);
1964                         ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
1965                         if (ret)
1966                                 return ret;
1967                 }
1968         }
1969
1970         return ret;
1971 }
1972
1973 /*
1974  * Count how many bytes are needed for an array of streaming descriptors.
1975  *
1976  * @priv1: pointer to a header, format or frame
1977  * @priv2: inout parameter, accumulated size of the array
1978  * @priv3: inout parameter, accumulated number of the array elements
1979  * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls
1980  */
1981 static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
1982                            enum uvcg_strm_type type)
1983 {
1984         size_t *size = priv2;
1985         size_t *count = priv3;
1986
1987         switch (type) {
1988         case UVCG_HEADER: {
1989                 struct uvcg_streaming_header *h = priv1;
1990
1991                 *size += sizeof(h->desc);
1992                 /* bmaControls */
1993                 *size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE;
1994         }
1995         break;
1996         case UVCG_FORMAT: {
1997                 struct uvcg_format *fmt = priv1;
1998
1999                 if (fmt->type == UVCG_UNCOMPRESSED) {
2000                         struct uvcg_uncompressed *u =
2001                                 container_of(fmt, struct uvcg_uncompressed,
2002                                              fmt);
2003
2004                         *size += sizeof(u->desc);
2005                 } else if (fmt->type == UVCG_MJPEG) {
2006                         struct uvcg_mjpeg *m =
2007                                 container_of(fmt, struct uvcg_mjpeg, fmt);
2008
2009                         *size += sizeof(m->desc);
2010                 } else {
2011                         return -EINVAL;
2012                 }
2013         }
2014         break;
2015         case UVCG_FRAME: {
2016                 struct uvcg_frame *frm = priv1;
2017                 int sz = sizeof(frm->dw_frame_interval);
2018
2019                 *size += sizeof(frm->frame);
2020                 *size += frm->frame.b_frame_interval_type * sz;
2021         }
2022         break;
2023         }
2024
2025         ++*count;
2026
2027         return 0;
2028 }
2029
2030 /*
2031  * Fill an array of streaming descriptors.
2032  *
2033  * @priv1: pointer to a header, format or frame
2034  * @priv2: inout parameter, pointer into a block of memory
2035  * @priv3: inout parameter, pointer to a 2-dimensional array
2036  */
2037 static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
2038                             enum uvcg_strm_type type)
2039 {
2040         void **dest = priv2;
2041         struct uvc_descriptor_header ***array = priv3;
2042         size_t sz;
2043
2044         **array = *dest;
2045         ++*array;
2046
2047         switch (type) {
2048         case UVCG_HEADER: {
2049                 struct uvc_input_header_descriptor *ihdr = *dest;
2050                 struct uvcg_streaming_header *h = priv1;
2051                 struct uvcg_format_ptr *f;
2052
2053                 memcpy(*dest, &h->desc, sizeof(h->desc));
2054                 *dest += sizeof(h->desc);
2055                 sz = UVCG_STREAMING_CONTROL_SIZE;
2056                 list_for_each_entry(f, &h->formats, entry) {
2057                         memcpy(*dest, f->fmt->bmaControls, sz);
2058                         *dest += sz;
2059                 }
2060                 ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz;
2061                 ihdr->bNumFormats = h->num_fmt;
2062         }
2063         break;
2064         case UVCG_FORMAT: {
2065                 struct uvcg_format *fmt = priv1;
2066
2067                 if (fmt->type == UVCG_UNCOMPRESSED) {
2068                         struct uvc_format_uncompressed *unc = *dest;
2069                         struct uvcg_uncompressed *u =
2070                                 container_of(fmt, struct uvcg_uncompressed,
2071                                              fmt);
2072
2073                         memcpy(*dest, &u->desc, sizeof(u->desc));
2074                         *dest += sizeof(u->desc);
2075                         unc->bNumFrameDescriptors = fmt->num_frames;
2076                         unc->bFormatIndex = n + 1;
2077                 } else if (fmt->type == UVCG_MJPEG) {
2078                         struct uvc_format_mjpeg *mjp = *dest;
2079                         struct uvcg_mjpeg *m =
2080                                 container_of(fmt, struct uvcg_mjpeg, fmt);
2081
2082                         memcpy(*dest, &m->desc, sizeof(m->desc));
2083                         *dest += sizeof(m->desc);
2084                         mjp->bNumFrameDescriptors = fmt->num_frames;
2085                         mjp->bFormatIndex = n + 1;
2086                 } else {
2087                         return -EINVAL;
2088                 }
2089         }
2090         break;
2091         case UVCG_FRAME: {
2092                 struct uvcg_frame *frm = priv1;
2093                 struct uvc_descriptor_header *h = *dest;
2094
2095                 sz = sizeof(frm->frame);
2096                 memcpy(*dest, &frm->frame, sz);
2097                 *dest += sz;
2098                 sz = frm->frame.b_frame_interval_type *
2099                         sizeof(*frm->dw_frame_interval);
2100                 memcpy(*dest, frm->dw_frame_interval, sz);
2101                 *dest += sz;
2102                 if (frm->fmt_type == UVCG_UNCOMPRESSED)
2103                         h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(
2104                                 frm->frame.b_frame_interval_type);
2105                 else if (frm->fmt_type == UVCG_MJPEG)
2106                         h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
2107                                 frm->frame.b_frame_interval_type);
2108         }
2109         break;
2110         }
2111
2112         return 0;
2113 }
2114
2115 static int uvcg_streaming_class_allow_link(struct config_item *src,
2116                                            struct config_item *target)
2117 {
2118         struct config_item *streaming, *header;
2119         struct f_uvc_opts *opts;
2120         struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
2121         struct uvc_descriptor_header ***class_array, **cl_arr;
2122         struct uvcg_streaming_header *target_hdr;
2123         void *data, *data_save;
2124         size_t size = 0, count = 0;
2125         int ret = -EINVAL;
2126
2127         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2128
2129         streaming = src->ci_parent->ci_parent;
2130         header = config_group_find_item(to_config_group(streaming), "header");
2131         if (!header || target->ci_parent != header)
2132                 goto out;
2133
2134         opts = to_f_uvc_opts(streaming->ci_parent);
2135
2136         mutex_lock(&opts->lock);
2137
2138         class_array = __uvcg_get_stream_class_arr(src, opts);
2139         if (!class_array || *class_array || opts->refcnt) {
2140                 ret = -EBUSY;
2141                 goto unlock;
2142         }
2143
2144         target_hdr = to_uvcg_streaming_header(target);
2145         ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm);
2146         if (ret)
2147                 goto unlock;
2148
2149         count += 2; /* color_matching, NULL */
2150         *class_array = kcalloc(count, sizeof(void *), GFP_KERNEL);
2151         if (!*class_array) {
2152                 ret = -ENOMEM;
2153                 goto unlock;
2154         }
2155
2156         data = data_save = kzalloc(size, GFP_KERNEL);
2157         if (!data) {
2158                 kfree(*class_array);
2159                 *class_array = NULL;
2160                 ret = PTR_ERR(data);
2161                 goto unlock;
2162         }
2163         cl_arr = *class_array;
2164         ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr,
2165                                    __uvcg_fill_strm);
2166         if (ret) {
2167                 kfree(*class_array);
2168                 *class_array = NULL;
2169                 /*
2170                  * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
2171                  * might have advanced the "data", so use a backup copy
2172                  */
2173                 kfree(data_save);
2174                 goto unlock;
2175         }
2176         *cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching;
2177
2178         ++target_hdr->linked;
2179         ret = 0;
2180
2181 unlock:
2182         mutex_unlock(&opts->lock);
2183 out:
2184         mutex_unlock(su_mutex);
2185         return ret;
2186 }
2187
2188 static int uvcg_streaming_class_drop_link(struct config_item *src,
2189                                           struct config_item *target)
2190 {
2191         struct config_item *streaming, *header;
2192         struct f_uvc_opts *opts;
2193         struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
2194         struct uvc_descriptor_header ***class_array;
2195         struct uvcg_streaming_header *target_hdr;
2196         int ret = -EINVAL;
2197
2198         mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2199
2200         streaming = src->ci_parent->ci_parent;
2201         header = config_group_find_item(to_config_group(streaming), "header");
2202         if (!header || target->ci_parent != header)
2203                 goto out;
2204
2205         opts = to_f_uvc_opts(streaming->ci_parent);
2206
2207         mutex_lock(&opts->lock);
2208
2209         class_array = __uvcg_get_stream_class_arr(src, opts);
2210         if (!class_array || !*class_array)
2211                 goto unlock;
2212
2213         if (opts->refcnt) {
2214                 ret = -EBUSY;
2215                 goto unlock;
2216         }
2217
2218         target_hdr = to_uvcg_streaming_header(target);
2219         --target_hdr->linked;
2220         kfree(**class_array);
2221         kfree(*class_array);
2222         *class_array = NULL;
2223         ret = 0;
2224
2225 unlock:
2226         mutex_unlock(&opts->lock);
2227 out:
2228         mutex_unlock(su_mutex);
2229         return ret;
2230 }
2231
2232 static struct configfs_item_operations uvcg_streaming_class_item_ops = {
2233         .allow_link     = uvcg_streaming_class_allow_link,
2234         .drop_link      = uvcg_streaming_class_drop_link,
2235 };
2236
2237 static struct config_item_type uvcg_streaming_class_type = {
2238         .ct_item_ops    = &uvcg_streaming_class_item_ops,
2239         .ct_owner       = THIS_MODULE,
2240 };
2241
2242 static struct config_group *uvcg_streaming_class_default_groups[] = {
2243         &uvcg_streaming_class_fs.group,
2244         &uvcg_streaming_class_hs.group,
2245         &uvcg_streaming_class_ss.group,
2246         NULL,
2247 };
2248
2249 /* streaming/class */
2250 static struct uvcg_streaming_class_grp {
2251         struct config_group     group;
2252 } uvcg_streaming_class_grp;
2253
2254 static struct config_item_type uvcg_streaming_class_grp_type = {
2255         .ct_owner = THIS_MODULE,
2256 };
2257
2258 static struct config_group *uvcg_streaming_default_groups[] = {
2259         &uvcg_streaming_header_grp.group,
2260         &uvcg_uncompressed_grp.group,
2261         &uvcg_mjpeg_grp.group,
2262         &uvcg_color_matching_grp.group,
2263         &uvcg_streaming_class_grp.group,
2264         NULL,
2265 };
2266
2267 /* streaming */
2268 static struct uvcg_streaming_grp {
2269         struct config_group     group;
2270 } uvcg_streaming_grp;
2271
2272 static struct config_item_type uvcg_streaming_grp_type = {
2273         .ct_owner = THIS_MODULE,
2274 };
2275
2276 static struct config_group *uvcg_default_groups[] = {
2277         &uvcg_control_grp.group,
2278         &uvcg_streaming_grp.group,
2279         NULL,
2280 };
2281
2282 static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item)
2283 {
2284         return container_of(to_config_group(item), struct f_uvc_opts,
2285                             func_inst.group);
2286 }
2287
2288 CONFIGFS_ATTR_STRUCT(f_uvc_opts);
2289 CONFIGFS_ATTR_OPS(f_uvc_opts);
2290
2291 static void uvc_attr_release(struct config_item *item)
2292 {
2293         struct f_uvc_opts *opts = to_f_uvc_opts(item);
2294
2295         usb_put_function_instance(&opts->func_inst);
2296 }
2297
2298 static struct configfs_item_operations uvc_item_ops = {
2299         .release                = uvc_attr_release,
2300         .show_attribute         = f_uvc_opts_attr_show,
2301         .store_attribute        = f_uvc_opts_attr_store,
2302 };
2303
2304 #define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit)            \
2305 static ssize_t f_uvc_opts_##cname##_show(                               \
2306         struct f_uvc_opts *opts, char *page)                            \
2307 {                                                                       \
2308         int result;                                                     \
2309                                                                         \
2310         mutex_lock(&opts->lock);                                        \
2311         result = sprintf(page, "%d\n", conv(opts->cname));              \
2312         mutex_unlock(&opts->lock);                                      \
2313                                                                         \
2314         return result;                                                  \
2315 }                                                                       \
2316                                                                         \
2317 static ssize_t                                                          \
2318 f_uvc_opts_##cname##_store(struct f_uvc_opts *opts,                     \
2319                            const char *page, size_t len)                \
2320 {                                                                       \
2321         int ret;                                                        \
2322         uxx num;                                                        \
2323                                                                         \
2324         mutex_lock(&opts->lock);                                        \
2325         if (opts->refcnt) {                                             \
2326                 ret = -EBUSY;                                           \
2327                 goto end;                                               \
2328         }                                                               \
2329                                                                         \
2330         ret = str2u(page, 0, &num);                                     \
2331         if (ret)                                                        \
2332                 goto end;                                               \
2333                                                                         \
2334         if (num > limit) {                                              \
2335                 ret = -EINVAL;                                          \
2336                 goto end;                                               \
2337         }                                                               \
2338         opts->cname = vnoc(num);                                        \
2339         ret = len;                                                      \
2340 end:                                                                    \
2341         mutex_unlock(&opts->lock);                                      \
2342         return ret;                                                     \
2343 }                                                                       \
2344                                                                         \
2345 static struct f_uvc_opts_attribute                                      \
2346         f_uvc_opts_attribute_##cname =                                  \
2347         __CONFIGFS_ATTR(cname, S_IRUGO | S_IWUSR,                       \
2348                         f_uvc_opts_##cname##_show,                      \
2349                         f_uvc_opts_##cname##_store)
2350
2351 #define identity_conv(x) (x)
2352
2353 UVCG_OPTS_ATTR(streaming_interval, identity_conv, kstrtou8, u8, identity_conv,
2354                16);
2355 UVCG_OPTS_ATTR(streaming_maxpacket, le16_to_cpu, kstrtou16, u16, le16_to_cpu,
2356                3072);
2357 UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv,
2358                15);
2359
2360 #undef identity_conv
2361
2362 #undef UVCG_OPTS_ATTR
2363
2364 static struct configfs_attribute *uvc_attrs[] = {
2365         &f_uvc_opts_attribute_streaming_interval.attr,
2366         &f_uvc_opts_attribute_streaming_maxpacket.attr,
2367         &f_uvc_opts_attribute_streaming_maxburst.attr,
2368         NULL,
2369 };
2370
2371 static struct config_item_type uvc_func_type = {
2372         .ct_item_ops    = &uvc_item_ops,
2373         .ct_attrs       = uvc_attrs,
2374         .ct_owner       = THIS_MODULE,
2375 };
2376
2377 static inline void uvcg_init_group(struct config_group *g,
2378                                    struct config_group **default_groups,
2379                                    const char *name,
2380                                    struct config_item_type *type)
2381 {
2382         g->default_groups = default_groups;
2383         config_group_init_type_name(g, name, type);
2384 }
2385
2386 int uvcg_attach_configfs(struct f_uvc_opts *opts)
2387 {
2388         config_group_init_type_name(&uvcg_control_header_grp.group,
2389                                     "header",
2390                                     &uvcg_control_header_grp_type);
2391         config_group_init_type_name(&uvcg_default_processing.group,
2392                                     "default",
2393                                     &uvcg_default_processing_type);
2394         uvcg_init_group(&uvcg_processing_grp.group,
2395                         uvcg_processing_default_groups,
2396                         "processing",
2397                         &uvcg_processing_grp_type);
2398         config_group_init_type_name(&uvcg_default_camera.group,
2399                                     "default",
2400                                     &uvcg_default_camera_type);
2401         uvcg_init_group(&uvcg_camera_grp.group,
2402                         uvcg_camera_default_groups,
2403                         "camera",
2404                         &uvcg_camera_grp_type);
2405         config_group_init_type_name(&uvcg_default_output.group,
2406                                     "default",
2407                                     &uvcg_default_output_type);
2408         uvcg_init_group(&uvcg_output_grp.group,
2409                         uvcg_output_default_groups,
2410                         "output",
2411                         &uvcg_output_grp_type);
2412         uvcg_init_group(&uvcg_terminal_grp.group,
2413                         uvcg_terminal_default_groups,
2414                         "terminal",
2415                         &uvcg_terminal_grp_type);
2416         config_group_init_type_name(&uvcg_control_class_fs.group,
2417                                     "fs",
2418                                     &uvcg_control_class_type);
2419         config_group_init_type_name(&uvcg_control_class_ss.group,
2420                                     "ss",
2421                                     &uvcg_control_class_type);
2422         uvcg_init_group(&uvcg_control_class_grp.group,
2423                         uvcg_control_class_default_groups,
2424                         "class",
2425                         &uvcg_control_class_grp_type);
2426         uvcg_init_group(&uvcg_control_grp.group,
2427                         uvcg_control_default_groups,
2428                         "control",
2429                         &uvcg_control_grp_type);
2430         config_group_init_type_name(&uvcg_streaming_header_grp.group,
2431                                     "header",
2432                                     &uvcg_streaming_header_grp_type);
2433         config_group_init_type_name(&uvcg_uncompressed_grp.group,
2434                                     "uncompressed",
2435                                     &uvcg_uncompressed_grp_type);
2436         config_group_init_type_name(&uvcg_mjpeg_grp.group,
2437                                     "mjpeg",
2438                                     &uvcg_mjpeg_grp_type);
2439         config_group_init_type_name(&uvcg_default_color_matching.group,
2440                                     "default",
2441                                     &uvcg_default_color_matching_type);
2442         uvcg_init_group(&uvcg_color_matching_grp.group,
2443                         uvcg_color_matching_default_groups,
2444                         "color_matching",
2445                         &uvcg_color_matching_grp_type);
2446         config_group_init_type_name(&uvcg_streaming_class_fs.group,
2447                                     "fs",
2448                                     &uvcg_streaming_class_type);
2449         config_group_init_type_name(&uvcg_streaming_class_hs.group,
2450                                     "hs",
2451                                     &uvcg_streaming_class_type);
2452         config_group_init_type_name(&uvcg_streaming_class_ss.group,
2453                                     "ss",
2454                                     &uvcg_streaming_class_type);
2455         uvcg_init_group(&uvcg_streaming_class_grp.group,
2456                         uvcg_streaming_class_default_groups,
2457                         "class",
2458                         &uvcg_streaming_class_grp_type);
2459         uvcg_init_group(&uvcg_streaming_grp.group,
2460                         uvcg_streaming_default_groups,
2461                         "streaming",
2462                         &uvcg_streaming_grp_type);
2463         uvcg_init_group(&opts->func_inst.group,
2464                         uvcg_default_groups,
2465                         "",
2466                         &uvc_func_type);
2467         return 0;
2468 }