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