1 // SPDX-License-Identifier: GPL-2.0
5 * Configfs support for the uvc function.
7 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
8 * http://www.samsung.com
10 * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
13 #include <linux/sort.h>
16 #include "uvc_configfs.h"
18 /* -----------------------------------------------------------------------------
19 * Global Utility Structures and Macros
22 #define UVCG_STREAMING_CONTROL_SIZE 1
24 #define UVC_ATTR(prefix, cname, aname) \
25 static struct configfs_attribute prefix##attr_##cname = { \
26 .ca_name = __stringify(aname), \
27 .ca_mode = S_IRUGO | S_IWUGO, \
28 .ca_owner = THIS_MODULE, \
29 .show = prefix##cname##_show, \
30 .store = prefix##cname##_store, \
33 #define UVC_ATTR_RO(prefix, cname, aname) \
34 static struct configfs_attribute prefix##attr_##cname = { \
35 .ca_name = __stringify(aname), \
37 .ca_owner = THIS_MODULE, \
38 .show = prefix##cname##_show, \
41 #define le8_to_cpu(x) (x)
42 #define cpu_to_le8(x) (x)
44 static int uvcg_config_compare_u32(const void *l
, const void *r
)
46 u32 li
= *(const u32
*)l
;
47 u32 ri
= *(const u32
*)r
;
49 return li
< ri
? -1 : li
== ri
? 0 : 1;
52 static inline struct f_uvc_opts
*to_f_uvc_opts(struct config_item
*item
)
54 return container_of(to_config_group(item
), struct f_uvc_opts
,
58 struct uvcg_config_group_type
{
59 struct config_item_type type
;
61 const struct uvcg_config_group_type
**children
;
62 int (*create_children
)(struct config_group
*group
);
65 static void uvcg_config_item_release(struct config_item
*item
)
67 struct config_group
*group
= to_config_group(item
);
72 static struct configfs_item_operations uvcg_config_item_ops
= {
73 .release
= uvcg_config_item_release
,
76 static int uvcg_config_create_group(struct config_group
*parent
,
77 const struct uvcg_config_group_type
*type
);
79 static int uvcg_config_create_children(struct config_group
*group
,
80 const struct uvcg_config_group_type
*type
)
82 const struct uvcg_config_group_type
**child
;
85 if (type
->create_children
)
86 return type
->create_children(group
);
88 for (child
= type
->children
; child
&& *child
; ++child
) {
89 ret
= uvcg_config_create_group(group
, *child
);
97 static int uvcg_config_create_group(struct config_group
*parent
,
98 const struct uvcg_config_group_type
*type
)
100 struct config_group
*group
;
102 group
= kzalloc(sizeof(*group
), GFP_KERNEL
);
106 config_group_init_type_name(group
, type
->name
, &type
->type
);
107 configfs_add_default_group(group
, parent
);
109 return uvcg_config_create_children(group
, type
);
112 static void uvcg_config_remove_children(struct config_group
*group
)
114 struct config_group
*child
, *n
;
116 list_for_each_entry_safe(child
, n
, &group
->default_groups
, group_entry
) {
117 list_del(&child
->group_entry
);
118 uvcg_config_remove_children(child
);
119 config_item_put(&child
->cg_item
);
123 /* -----------------------------------------------------------------------------
124 * control/header/<NAME>
128 DECLARE_UVC_HEADER_DESCRIPTOR(1);
130 struct uvcg_control_header
{
131 struct config_item item
;
132 struct UVC_HEADER_DESCRIPTOR(1) desc
;
136 static struct uvcg_control_header
*to_uvcg_control_header(struct config_item
*item
)
138 return container_of(item
, struct uvcg_control_header
, item
);
141 #define UVCG_CTRL_HDR_ATTR(cname, aname, bits, limit) \
142 static ssize_t uvcg_control_header_##cname##_show( \
143 struct config_item *item, char *page) \
145 struct uvcg_control_header *ch = to_uvcg_control_header(item); \
146 struct f_uvc_opts *opts; \
147 struct config_item *opts_item; \
148 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
151 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
153 opts_item = ch->item.ci_parent->ci_parent->ci_parent; \
154 opts = to_f_uvc_opts(opts_item); \
156 mutex_lock(&opts->lock); \
157 result = sprintf(page, "%u\n", le##bits##_to_cpu(ch->desc.aname));\
158 mutex_unlock(&opts->lock); \
160 mutex_unlock(su_mutex); \
165 uvcg_control_header_##cname##_store(struct config_item *item, \
166 const char *page, size_t len) \
168 struct uvcg_control_header *ch = to_uvcg_control_header(item); \
169 struct f_uvc_opts *opts; \
170 struct config_item *opts_item; \
171 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
175 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
177 opts_item = ch->item.ci_parent->ci_parent->ci_parent; \
178 opts = to_f_uvc_opts(opts_item); \
180 mutex_lock(&opts->lock); \
181 if (ch->linked || opts->refcnt) { \
186 ret = kstrtou##bits(page, 0, &num); \
194 ch->desc.aname = cpu_to_le##bits(num); \
197 mutex_unlock(&opts->lock); \
198 mutex_unlock(su_mutex); \
202 UVC_ATTR(uvcg_control_header_, cname, aname)
204 UVCG_CTRL_HDR_ATTR(bcd_uvc
, bcdUVC
, 16, 0xffff);
206 UVCG_CTRL_HDR_ATTR(dw_clock_frequency
, dwClockFrequency
, 32, 0x7fffffff);
208 #undef UVCG_CTRL_HDR_ATTR
210 static struct configfs_attribute
*uvcg_control_header_attrs
[] = {
211 &uvcg_control_header_attr_bcd_uvc
,
212 &uvcg_control_header_attr_dw_clock_frequency
,
216 static const struct config_item_type uvcg_control_header_type
= {
217 .ct_item_ops
= &uvcg_config_item_ops
,
218 .ct_attrs
= uvcg_control_header_attrs
,
219 .ct_owner
= THIS_MODULE
,
222 static struct config_item
*uvcg_control_header_make(struct config_group
*group
,
225 struct uvcg_control_header
*h
;
227 h
= kzalloc(sizeof(*h
), GFP_KERNEL
);
229 return ERR_PTR(-ENOMEM
);
231 h
->desc
.bLength
= UVC_DT_HEADER_SIZE(1);
232 h
->desc
.bDescriptorType
= USB_DT_CS_INTERFACE
;
233 h
->desc
.bDescriptorSubType
= UVC_VC_HEADER
;
234 h
->desc
.bcdUVC
= cpu_to_le16(0x0100);
235 h
->desc
.dwClockFrequency
= cpu_to_le32(48000000);
237 config_item_init_type_name(&h
->item
, name
, &uvcg_control_header_type
);
242 static struct configfs_group_operations uvcg_control_header_grp_ops
= {
243 .make_item
= uvcg_control_header_make
,
246 static const struct uvcg_config_group_type uvcg_control_header_grp_type
= {
248 .ct_item_ops
= &uvcg_config_item_ops
,
249 .ct_group_ops
= &uvcg_control_header_grp_ops
,
250 .ct_owner
= THIS_MODULE
,
255 /* -----------------------------------------------------------------------------
256 * control/processing/default
259 #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, bits) \
260 static ssize_t uvcg_default_processing_##cname##_show( \
261 struct config_item *item, char *page) \
263 struct config_group *group = to_config_group(item); \
264 struct f_uvc_opts *opts; \
265 struct config_item *opts_item; \
266 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \
267 struct uvc_processing_unit_descriptor *pd; \
270 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
272 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \
273 opts = to_f_uvc_opts(opts_item); \
274 pd = &opts->uvc_processing; \
276 mutex_lock(&opts->lock); \
277 result = sprintf(page, "%u\n", le##bits##_to_cpu(pd->aname)); \
278 mutex_unlock(&opts->lock); \
280 mutex_unlock(su_mutex); \
284 UVC_ATTR_RO(uvcg_default_processing_, cname, aname)
286 UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id
, bUnitID
, 8);
287 UVCG_DEFAULT_PROCESSING_ATTR(b_source_id
, bSourceID
, 8);
288 UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier
, wMaxMultiplier
, 16);
289 UVCG_DEFAULT_PROCESSING_ATTR(i_processing
, iProcessing
, 8);
291 #undef UVCG_DEFAULT_PROCESSING_ATTR
293 static ssize_t
uvcg_default_processing_bm_controls_show(
294 struct config_item
*item
, char *page
)
296 struct config_group
*group
= to_config_group(item
);
297 struct f_uvc_opts
*opts
;
298 struct config_item
*opts_item
;
299 struct mutex
*su_mutex
= &group
->cg_subsys
->su_mutex
;
300 struct uvc_processing_unit_descriptor
*pd
;
304 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
306 opts_item
= group
->cg_item
.ci_parent
->ci_parent
->ci_parent
;
307 opts
= to_f_uvc_opts(opts_item
);
308 pd
= &opts
->uvc_processing
;
310 mutex_lock(&opts
->lock
);
311 for (result
= 0, i
= 0; i
< pd
->bControlSize
; ++i
) {
312 result
+= sprintf(pg
, "%u\n", pd
->bmControls
[i
]);
315 mutex_unlock(&opts
->lock
);
317 mutex_unlock(su_mutex
);
322 UVC_ATTR_RO(uvcg_default_processing_
, bm_controls
, bmControls
);
324 static struct configfs_attribute
*uvcg_default_processing_attrs
[] = {
325 &uvcg_default_processing_attr_b_unit_id
,
326 &uvcg_default_processing_attr_b_source_id
,
327 &uvcg_default_processing_attr_w_max_multiplier
,
328 &uvcg_default_processing_attr_bm_controls
,
329 &uvcg_default_processing_attr_i_processing
,
333 static const struct uvcg_config_group_type uvcg_default_processing_type
= {
335 .ct_item_ops
= &uvcg_config_item_ops
,
336 .ct_attrs
= uvcg_default_processing_attrs
,
337 .ct_owner
= THIS_MODULE
,
342 /* -----------------------------------------------------------------------------
346 static const struct uvcg_config_group_type uvcg_processing_grp_type
= {
348 .ct_item_ops
= &uvcg_config_item_ops
,
349 .ct_owner
= THIS_MODULE
,
351 .name
= "processing",
352 .children
= (const struct uvcg_config_group_type
*[]) {
353 &uvcg_default_processing_type
,
358 /* -----------------------------------------------------------------------------
359 * control/terminal/camera/default
362 #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, bits) \
363 static ssize_t uvcg_default_camera_##cname##_show( \
364 struct config_item *item, char *page) \
366 struct config_group *group = to_config_group(item); \
367 struct f_uvc_opts *opts; \
368 struct config_item *opts_item; \
369 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \
370 struct uvc_camera_terminal_descriptor *cd; \
373 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
375 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> \
377 opts = to_f_uvc_opts(opts_item); \
378 cd = &opts->uvc_camera_terminal; \
380 mutex_lock(&opts->lock); \
381 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \
382 mutex_unlock(&opts->lock); \
384 mutex_unlock(su_mutex); \
389 UVC_ATTR_RO(uvcg_default_camera_, cname, aname)
391 UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id
, bTerminalID
, 8);
392 UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type
, wTerminalType
, 16);
393 UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal
, bAssocTerminal
, 8);
394 UVCG_DEFAULT_CAMERA_ATTR(i_terminal
, iTerminal
, 8);
395 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min
, wObjectiveFocalLengthMin
,
397 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max
, wObjectiveFocalLengthMax
,
399 UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length
, wOcularFocalLength
,
402 #undef UVCG_DEFAULT_CAMERA_ATTR
404 static ssize_t
uvcg_default_camera_bm_controls_show(
405 struct config_item
*item
, char *page
)
407 struct config_group
*group
= to_config_group(item
);
408 struct f_uvc_opts
*opts
;
409 struct config_item
*opts_item
;
410 struct mutex
*su_mutex
= &group
->cg_subsys
->su_mutex
;
411 struct uvc_camera_terminal_descriptor
*cd
;
415 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
417 opts_item
= group
->cg_item
.ci_parent
->ci_parent
->ci_parent
->
419 opts
= to_f_uvc_opts(opts_item
);
420 cd
= &opts
->uvc_camera_terminal
;
422 mutex_lock(&opts
->lock
);
423 for (result
= 0, i
= 0; i
< cd
->bControlSize
; ++i
) {
424 result
+= sprintf(pg
, "%u\n", cd
->bmControls
[i
]);
427 mutex_unlock(&opts
->lock
);
429 mutex_unlock(su_mutex
);
433 UVC_ATTR_RO(uvcg_default_camera_
, bm_controls
, bmControls
);
435 static struct configfs_attribute
*uvcg_default_camera_attrs
[] = {
436 &uvcg_default_camera_attr_b_terminal_id
,
437 &uvcg_default_camera_attr_w_terminal_type
,
438 &uvcg_default_camera_attr_b_assoc_terminal
,
439 &uvcg_default_camera_attr_i_terminal
,
440 &uvcg_default_camera_attr_w_objective_focal_length_min
,
441 &uvcg_default_camera_attr_w_objective_focal_length_max
,
442 &uvcg_default_camera_attr_w_ocular_focal_length
,
443 &uvcg_default_camera_attr_bm_controls
,
447 static const struct uvcg_config_group_type uvcg_default_camera_type
= {
449 .ct_item_ops
= &uvcg_config_item_ops
,
450 .ct_attrs
= uvcg_default_camera_attrs
,
451 .ct_owner
= THIS_MODULE
,
456 /* -----------------------------------------------------------------------------
457 * control/terminal/camera
460 static const struct uvcg_config_group_type uvcg_camera_grp_type
= {
462 .ct_item_ops
= &uvcg_config_item_ops
,
463 .ct_owner
= THIS_MODULE
,
466 .children
= (const struct uvcg_config_group_type
*[]) {
467 &uvcg_default_camera_type
,
472 /* -----------------------------------------------------------------------------
473 * control/terminal/output/default
476 #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, bits) \
477 static ssize_t uvcg_default_output_##cname##_show( \
478 struct config_item *item, char *page) \
480 struct config_group *group = to_config_group(item); \
481 struct f_uvc_opts *opts; \
482 struct config_item *opts_item; \
483 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \
484 struct uvc_output_terminal_descriptor *cd; \
487 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
489 opts_item = group->cg_item.ci_parent->ci_parent-> \
490 ci_parent->ci_parent; \
491 opts = to_f_uvc_opts(opts_item); \
492 cd = &opts->uvc_output_terminal; \
494 mutex_lock(&opts->lock); \
495 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \
496 mutex_unlock(&opts->lock); \
498 mutex_unlock(su_mutex); \
503 UVC_ATTR_RO(uvcg_default_output_, cname, aname)
505 UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id
, bTerminalID
, 8);
506 UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type
, wTerminalType
, 16);
507 UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal
, bAssocTerminal
, 8);
508 UVCG_DEFAULT_OUTPUT_ATTR(b_source_id
, bSourceID
, 8);
509 UVCG_DEFAULT_OUTPUT_ATTR(i_terminal
, iTerminal
, 8);
511 #undef UVCG_DEFAULT_OUTPUT_ATTR
513 static struct configfs_attribute
*uvcg_default_output_attrs
[] = {
514 &uvcg_default_output_attr_b_terminal_id
,
515 &uvcg_default_output_attr_w_terminal_type
,
516 &uvcg_default_output_attr_b_assoc_terminal
,
517 &uvcg_default_output_attr_b_source_id
,
518 &uvcg_default_output_attr_i_terminal
,
522 static const struct uvcg_config_group_type uvcg_default_output_type
= {
524 .ct_item_ops
= &uvcg_config_item_ops
,
525 .ct_attrs
= uvcg_default_output_attrs
,
526 .ct_owner
= THIS_MODULE
,
531 /* -----------------------------------------------------------------------------
532 * control/terminal/output
535 static const struct uvcg_config_group_type uvcg_output_grp_type
= {
537 .ct_item_ops
= &uvcg_config_item_ops
,
538 .ct_owner
= THIS_MODULE
,
541 .children
= (const struct uvcg_config_group_type
*[]) {
542 &uvcg_default_output_type
,
547 /* -----------------------------------------------------------------------------
551 static const struct uvcg_config_group_type uvcg_terminal_grp_type
= {
553 .ct_item_ops
= &uvcg_config_item_ops
,
554 .ct_owner
= THIS_MODULE
,
557 .children
= (const struct uvcg_config_group_type
*[]) {
558 &uvcg_camera_grp_type
,
559 &uvcg_output_grp_type
,
564 /* -----------------------------------------------------------------------------
565 * control/class/{fs|ss}
568 struct uvcg_control_class_group
{
569 struct config_group group
;
573 static inline struct uvc_descriptor_header
574 **uvcg_get_ctl_class_arr(struct config_item
*i
, struct f_uvc_opts
*o
)
576 struct uvcg_control_class_group
*group
=
577 container_of(i
, struct uvcg_control_class_group
,
580 if (!strcmp(group
->name
, "fs"))
581 return o
->uvc_fs_control_cls
;
583 if (!strcmp(group
->name
, "ss"))
584 return o
->uvc_ss_control_cls
;
589 static int uvcg_control_class_allow_link(struct config_item
*src
,
590 struct config_item
*target
)
592 struct config_item
*control
, *header
;
593 struct f_uvc_opts
*opts
;
594 struct mutex
*su_mutex
= &src
->ci_group
->cg_subsys
->su_mutex
;
595 struct uvc_descriptor_header
**class_array
;
596 struct uvcg_control_header
*target_hdr
;
599 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
601 control
= src
->ci_parent
->ci_parent
;
602 header
= config_group_find_item(to_config_group(control
), "header");
603 if (!header
|| target
->ci_parent
!= header
)
606 opts
= to_f_uvc_opts(control
->ci_parent
);
608 mutex_lock(&opts
->lock
);
610 class_array
= uvcg_get_ctl_class_arr(src
, opts
);
613 if (opts
->refcnt
|| class_array
[0]) {
618 target_hdr
= to_uvcg_control_header(target
);
619 ++target_hdr
->linked
;
620 class_array
[0] = (struct uvc_descriptor_header
*)&target_hdr
->desc
;
624 mutex_unlock(&opts
->lock
);
626 config_item_put(header
);
627 mutex_unlock(su_mutex
);
631 static void uvcg_control_class_drop_link(struct config_item
*src
,
632 struct config_item
*target
)
634 struct config_item
*control
, *header
;
635 struct f_uvc_opts
*opts
;
636 struct mutex
*su_mutex
= &src
->ci_group
->cg_subsys
->su_mutex
;
637 struct uvc_descriptor_header
**class_array
;
638 struct uvcg_control_header
*target_hdr
;
640 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
642 control
= src
->ci_parent
->ci_parent
;
643 header
= config_group_find_item(to_config_group(control
), "header");
644 if (!header
|| target
->ci_parent
!= header
)
647 opts
= to_f_uvc_opts(control
->ci_parent
);
649 mutex_lock(&opts
->lock
);
651 class_array
= uvcg_get_ctl_class_arr(src
, opts
);
652 if (!class_array
|| opts
->refcnt
)
655 target_hdr
= to_uvcg_control_header(target
);
656 --target_hdr
->linked
;
657 class_array
[0] = NULL
;
660 mutex_unlock(&opts
->lock
);
662 config_item_put(header
);
663 mutex_unlock(su_mutex
);
666 static struct configfs_item_operations uvcg_control_class_item_ops
= {
667 .release
= uvcg_config_item_release
,
668 .allow_link
= uvcg_control_class_allow_link
,
669 .drop_link
= uvcg_control_class_drop_link
,
672 static const struct config_item_type uvcg_control_class_type
= {
673 .ct_item_ops
= &uvcg_control_class_item_ops
,
674 .ct_owner
= THIS_MODULE
,
677 /* -----------------------------------------------------------------------------
681 static int uvcg_control_class_create_children(struct config_group
*parent
)
683 static const char * const names
[] = { "fs", "ss" };
686 for (i
= 0; i
< ARRAY_SIZE(names
); ++i
) {
687 struct uvcg_control_class_group
*group
;
689 group
= kzalloc(sizeof(*group
), GFP_KERNEL
);
693 group
->name
= names
[i
];
695 config_group_init_type_name(&group
->group
, group
->name
,
696 &uvcg_control_class_type
);
697 configfs_add_default_group(&group
->group
, parent
);
703 static const struct uvcg_config_group_type uvcg_control_class_grp_type
= {
705 .ct_item_ops
= &uvcg_config_item_ops
,
706 .ct_owner
= THIS_MODULE
,
709 .create_children
= uvcg_control_class_create_children
,
712 /* -----------------------------------------------------------------------------
716 static ssize_t
uvcg_default_control_b_interface_number_show(
717 struct config_item
*item
, char *page
)
719 struct config_group
*group
= to_config_group(item
);
720 struct mutex
*su_mutex
= &group
->cg_subsys
->su_mutex
;
721 struct config_item
*opts_item
;
722 struct f_uvc_opts
*opts
;
725 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
727 opts_item
= item
->ci_parent
;
728 opts
= to_f_uvc_opts(opts_item
);
730 mutex_lock(&opts
->lock
);
731 result
+= sprintf(page
, "%u\n", opts
->control_interface
);
732 mutex_unlock(&opts
->lock
);
734 mutex_unlock(su_mutex
);
739 UVC_ATTR_RO(uvcg_default_control_
, b_interface_number
, bInterfaceNumber
);
741 static struct configfs_attribute
*uvcg_default_control_attrs
[] = {
742 &uvcg_default_control_attr_b_interface_number
,
746 static const struct uvcg_config_group_type uvcg_control_grp_type
= {
748 .ct_item_ops
= &uvcg_config_item_ops
,
749 .ct_attrs
= uvcg_default_control_attrs
,
750 .ct_owner
= THIS_MODULE
,
753 .children
= (const struct uvcg_config_group_type
*[]) {
754 &uvcg_control_header_grp_type
,
755 &uvcg_processing_grp_type
,
756 &uvcg_terminal_grp_type
,
757 &uvcg_control_class_grp_type
,
762 /* -----------------------------------------------------------------------------
763 * streaming/uncompressed
767 static const char * const uvcg_format_names
[] = {
772 enum uvcg_format_type
{
773 UVCG_UNCOMPRESSED
= 0,
778 struct config_group group
;
779 enum uvcg_format_type type
;
782 __u8 bmaControls
[UVCG_STREAMING_CONTROL_SIZE
];
785 static struct uvcg_format
*to_uvcg_format(struct config_item
*item
)
787 return container_of(to_config_group(item
), struct uvcg_format
, group
);
790 static ssize_t
uvcg_format_bma_controls_show(struct uvcg_format
*f
, char *page
)
792 struct f_uvc_opts
*opts
;
793 struct config_item
*opts_item
;
794 struct mutex
*su_mutex
= &f
->group
.cg_subsys
->su_mutex
;
798 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
800 opts_item
= f
->group
.cg_item
.ci_parent
->ci_parent
->ci_parent
;
801 opts
= to_f_uvc_opts(opts_item
);
803 mutex_lock(&opts
->lock
);
804 result
= sprintf(pg
, "0x");
806 for (i
= 0; i
< UVCG_STREAMING_CONTROL_SIZE
; ++i
) {
807 result
+= sprintf(pg
, "%x\n", f
->bmaControls
[i
]);
810 mutex_unlock(&opts
->lock
);
812 mutex_unlock(su_mutex
);
816 static ssize_t
uvcg_format_bma_controls_store(struct uvcg_format
*ch
,
817 const char *page
, size_t len
)
819 struct f_uvc_opts
*opts
;
820 struct config_item
*opts_item
;
821 struct mutex
*su_mutex
= &ch
->group
.cg_subsys
->su_mutex
;
824 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
826 opts_item
= ch
->group
.cg_item
.ci_parent
->ci_parent
->ci_parent
;
827 opts
= to_f_uvc_opts(opts_item
);
829 mutex_lock(&opts
->lock
);
830 if (ch
->linked
|| opts
->refcnt
) {
835 if (len
< 4 || *page
!= '0' ||
836 (*(page
+ 1) != 'x' && *(page
+ 1) != 'X'))
838 ret
= hex2bin(ch
->bmaControls
, page
+ 2, 1);
843 mutex_unlock(&opts
->lock
);
844 mutex_unlock(su_mutex
);
848 struct uvcg_format_ptr
{
849 struct uvcg_format
*fmt
;
850 struct list_head entry
;
853 /* -----------------------------------------------------------------------------
854 * streaming/header/<NAME>
858 struct uvcg_streaming_header
{
859 struct config_item item
;
860 struct uvc_input_header_descriptor desc
;
862 struct list_head formats
;
866 static struct uvcg_streaming_header
*to_uvcg_streaming_header(struct config_item
*item
)
868 return container_of(item
, struct uvcg_streaming_header
, item
);
871 static void uvcg_format_set_indices(struct config_group
*fmt
);
873 static int uvcg_streaming_header_allow_link(struct config_item
*src
,
874 struct config_item
*target
)
876 struct mutex
*su_mutex
= &src
->ci_group
->cg_subsys
->su_mutex
;
877 struct config_item
*opts_item
;
878 struct f_uvc_opts
*opts
;
879 struct uvcg_streaming_header
*src_hdr
;
880 struct uvcg_format
*target_fmt
= NULL
;
881 struct uvcg_format_ptr
*format_ptr
;
882 int i
, ret
= -EINVAL
;
884 src_hdr
= to_uvcg_streaming_header(src
);
885 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
887 opts_item
= src
->ci_parent
->ci_parent
->ci_parent
;
888 opts
= to_f_uvc_opts(opts_item
);
890 mutex_lock(&opts
->lock
);
892 if (src_hdr
->linked
) {
898 * Linking is only allowed to direct children of the format nodes
899 * (streaming/uncompressed or streaming/mjpeg nodes). First check that
900 * the grand-parent of the target matches the grand-parent of the source
901 * (the streaming node), and then verify that the target parent is a
904 if (src
->ci_parent
->ci_parent
!= target
->ci_parent
->ci_parent
)
907 for (i
= 0; i
< ARRAY_SIZE(uvcg_format_names
); ++i
) {
908 if (!strcmp(target
->ci_parent
->ci_name
, uvcg_format_names
[i
]))
912 if (i
== ARRAY_SIZE(uvcg_format_names
))
915 target_fmt
= container_of(to_config_group(target
), struct uvcg_format
,
920 uvcg_format_set_indices(to_config_group(target
));
922 format_ptr
= kzalloc(sizeof(*format_ptr
), GFP_KERNEL
);
928 format_ptr
->fmt
= target_fmt
;
929 list_add_tail(&format_ptr
->entry
, &src_hdr
->formats
);
931 ++target_fmt
->linked
;
934 mutex_unlock(&opts
->lock
);
935 mutex_unlock(su_mutex
);
939 static void uvcg_streaming_header_drop_link(struct config_item
*src
,
940 struct config_item
*target
)
942 struct mutex
*su_mutex
= &src
->ci_group
->cg_subsys
->su_mutex
;
943 struct config_item
*opts_item
;
944 struct f_uvc_opts
*opts
;
945 struct uvcg_streaming_header
*src_hdr
;
946 struct uvcg_format
*target_fmt
= NULL
;
947 struct uvcg_format_ptr
*format_ptr
, *tmp
;
949 src_hdr
= to_uvcg_streaming_header(src
);
950 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
952 opts_item
= src
->ci_parent
->ci_parent
->ci_parent
;
953 opts
= to_f_uvc_opts(opts_item
);
955 mutex_lock(&opts
->lock
);
956 target_fmt
= container_of(to_config_group(target
), struct uvcg_format
,
961 list_for_each_entry_safe(format_ptr
, tmp
, &src_hdr
->formats
, entry
)
962 if (format_ptr
->fmt
== target_fmt
) {
963 list_del(&format_ptr
->entry
);
969 --target_fmt
->linked
;
972 mutex_unlock(&opts
->lock
);
973 mutex_unlock(su_mutex
);
976 static struct configfs_item_operations uvcg_streaming_header_item_ops
= {
977 .release
= uvcg_config_item_release
,
978 .allow_link
= uvcg_streaming_header_allow_link
,
979 .drop_link
= uvcg_streaming_header_drop_link
,
982 #define UVCG_STREAMING_HEADER_ATTR(cname, aname, bits) \
983 static ssize_t uvcg_streaming_header_##cname##_show( \
984 struct config_item *item, char *page) \
986 struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \
987 struct f_uvc_opts *opts; \
988 struct config_item *opts_item; \
989 struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\
992 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
994 opts_item = sh->item.ci_parent->ci_parent->ci_parent; \
995 opts = to_f_uvc_opts(opts_item); \
997 mutex_lock(&opts->lock); \
998 result = sprintf(page, "%u\n", le##bits##_to_cpu(sh->desc.aname));\
999 mutex_unlock(&opts->lock); \
1001 mutex_unlock(su_mutex); \
1005 UVC_ATTR_RO(uvcg_streaming_header_, cname, aname)
1007 UVCG_STREAMING_HEADER_ATTR(bm_info
, bmInfo
, 8);
1008 UVCG_STREAMING_HEADER_ATTR(b_terminal_link
, bTerminalLink
, 8);
1009 UVCG_STREAMING_HEADER_ATTR(b_still_capture_method
, bStillCaptureMethod
, 8);
1010 UVCG_STREAMING_HEADER_ATTR(b_trigger_support
, bTriggerSupport
, 8);
1011 UVCG_STREAMING_HEADER_ATTR(b_trigger_usage
, bTriggerUsage
, 8);
1013 #undef UVCG_STREAMING_HEADER_ATTR
1015 static struct configfs_attribute
*uvcg_streaming_header_attrs
[] = {
1016 &uvcg_streaming_header_attr_bm_info
,
1017 &uvcg_streaming_header_attr_b_terminal_link
,
1018 &uvcg_streaming_header_attr_b_still_capture_method
,
1019 &uvcg_streaming_header_attr_b_trigger_support
,
1020 &uvcg_streaming_header_attr_b_trigger_usage
,
1024 static const struct config_item_type uvcg_streaming_header_type
= {
1025 .ct_item_ops
= &uvcg_streaming_header_item_ops
,
1026 .ct_attrs
= uvcg_streaming_header_attrs
,
1027 .ct_owner
= THIS_MODULE
,
1030 static struct config_item
1031 *uvcg_streaming_header_make(struct config_group
*group
, const char *name
)
1033 struct uvcg_streaming_header
*h
;
1035 h
= kzalloc(sizeof(*h
), GFP_KERNEL
);
1037 return ERR_PTR(-ENOMEM
);
1039 INIT_LIST_HEAD(&h
->formats
);
1040 h
->desc
.bDescriptorType
= USB_DT_CS_INTERFACE
;
1041 h
->desc
.bDescriptorSubType
= UVC_VS_INPUT_HEADER
;
1042 h
->desc
.bTerminalLink
= 3;
1043 h
->desc
.bControlSize
= UVCG_STREAMING_CONTROL_SIZE
;
1045 config_item_init_type_name(&h
->item
, name
, &uvcg_streaming_header_type
);
1050 static struct configfs_group_operations uvcg_streaming_header_grp_ops
= {
1051 .make_item
= uvcg_streaming_header_make
,
1054 static const struct uvcg_config_group_type uvcg_streaming_header_grp_type
= {
1056 .ct_item_ops
= &uvcg_config_item_ops
,
1057 .ct_group_ops
= &uvcg_streaming_header_grp_ops
,
1058 .ct_owner
= THIS_MODULE
,
1063 /* -----------------------------------------------------------------------------
1064 * streaming/<mode>/<format>/<NAME>
1068 struct config_item item
;
1069 enum uvcg_format_type fmt_type
;
1072 u8 b_descriptor_type
;
1073 u8 b_descriptor_subtype
;
1078 u32 dw_min_bit_rate
;
1079 u32 dw_max_bit_rate
;
1080 u32 dw_max_video_frame_buffer_size
;
1081 u32 dw_default_frame_interval
;
1082 u8 b_frame_interval_type
;
1083 } __attribute__((packed
)) frame
;
1084 u32
*dw_frame_interval
;
1087 static struct uvcg_frame
*to_uvcg_frame(struct config_item
*item
)
1089 return container_of(item
, struct uvcg_frame
, item
);
1092 #define UVCG_FRAME_ATTR(cname, aname, bits) \
1093 static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
1095 struct uvcg_frame *f = to_uvcg_frame(item); \
1096 struct f_uvc_opts *opts; \
1097 struct config_item *opts_item; \
1098 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1101 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1103 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \
1104 opts = to_f_uvc_opts(opts_item); \
1106 mutex_lock(&opts->lock); \
1107 result = sprintf(page, "%u\n", f->frame.cname); \
1108 mutex_unlock(&opts->lock); \
1110 mutex_unlock(su_mutex); \
1114 static ssize_t uvcg_frame_##cname##_store(struct config_item *item, \
1115 const char *page, size_t len)\
1117 struct uvcg_frame *f = to_uvcg_frame(item); \
1118 struct f_uvc_opts *opts; \
1119 struct config_item *opts_item; \
1120 struct uvcg_format *fmt; \
1121 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1122 typeof(f->frame.cname) num; \
1125 ret = kstrtou##bits(page, 0, &num); \
1129 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1131 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \
1132 opts = to_f_uvc_opts(opts_item); \
1133 fmt = to_uvcg_format(f->item.ci_parent); \
1135 mutex_lock(&opts->lock); \
1136 if (fmt->linked || opts->refcnt) { \
1141 f->frame.cname = num; \
1144 mutex_unlock(&opts->lock); \
1145 mutex_unlock(su_mutex); \
1149 UVC_ATTR(uvcg_frame_, cname, aname);
1151 static ssize_t
uvcg_frame_b_frame_index_show(struct config_item
*item
,
1154 struct uvcg_frame
*f
= to_uvcg_frame(item
);
1155 struct uvcg_format
*fmt
;
1156 struct f_uvc_opts
*opts
;
1157 struct config_item
*opts_item
;
1158 struct config_item
*fmt_item
;
1159 struct mutex
*su_mutex
= &f
->item
.ci_group
->cg_subsys
->su_mutex
;
1162 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
1164 fmt_item
= f
->item
.ci_parent
;
1165 fmt
= to_uvcg_format(fmt_item
);
1172 opts_item
= fmt_item
->ci_parent
->ci_parent
->ci_parent
;
1173 opts
= to_f_uvc_opts(opts_item
);
1175 mutex_lock(&opts
->lock
);
1176 result
= sprintf(page
, "%u\n", f
->frame
.b_frame_index
);
1177 mutex_unlock(&opts
->lock
);
1180 mutex_unlock(su_mutex
);
1184 UVC_ATTR_RO(uvcg_frame_
, b_frame_index
, bFrameIndex
);
1186 UVCG_FRAME_ATTR(bm_capabilities
, bmCapabilities
, 8);
1187 UVCG_FRAME_ATTR(w_width
, wWidth
, 16);
1188 UVCG_FRAME_ATTR(w_height
, wHeight
, 16);
1189 UVCG_FRAME_ATTR(dw_min_bit_rate
, dwMinBitRate
, 32);
1190 UVCG_FRAME_ATTR(dw_max_bit_rate
, dwMaxBitRate
, 32);
1191 UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size
, dwMaxVideoFrameBufferSize
, 32);
1192 UVCG_FRAME_ATTR(dw_default_frame_interval
, dwDefaultFrameInterval
, 32);
1194 #undef UVCG_FRAME_ATTR
1196 static ssize_t
uvcg_frame_dw_frame_interval_show(struct config_item
*item
,
1199 struct uvcg_frame
*frm
= to_uvcg_frame(item
);
1200 struct f_uvc_opts
*opts
;
1201 struct config_item
*opts_item
;
1202 struct mutex
*su_mutex
= &frm
->item
.ci_group
->cg_subsys
->su_mutex
;
1206 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
1208 opts_item
= frm
->item
.ci_parent
->ci_parent
->ci_parent
->ci_parent
;
1209 opts
= to_f_uvc_opts(opts_item
);
1211 mutex_lock(&opts
->lock
);
1212 for (result
= 0, i
= 0; i
< frm
->frame
.b_frame_interval_type
; ++i
) {
1213 result
+= sprintf(pg
, "%u\n", frm
->dw_frame_interval
[i
]);
1216 mutex_unlock(&opts
->lock
);
1218 mutex_unlock(su_mutex
);
1222 static inline int __uvcg_count_frm_intrv(char *buf
, void *priv
)
1228 static inline int __uvcg_fill_frm_intrv(char *buf
, void *priv
)
1233 ret
= kstrtou32(buf
, 0, &num
);
1244 static int __uvcg_iter_frm_intrv(const char *page
, size_t len
,
1245 int (*fun
)(char *, void *), void *priv
)
1247 /* sign, base 2 representation, newline, terminator */
1248 char buf
[1 + sizeof(u32
) * 8 + 1 + 1];
1249 const char *pg
= page
;
1255 while (pg
- page
< len
) {
1257 while (i
< sizeof(buf
) && (pg
- page
< len
) &&
1258 *pg
!= '\0' && *pg
!= '\n')
1260 if (i
== sizeof(buf
))
1262 while ((pg
- page
< len
) && (*pg
== '\0' || *pg
== '\n'))
1265 ret
= fun(buf
, priv
);
1273 static ssize_t
uvcg_frame_dw_frame_interval_store(struct config_item
*item
,
1274 const char *page
, size_t len
)
1276 struct uvcg_frame
*ch
= to_uvcg_frame(item
);
1277 struct f_uvc_opts
*opts
;
1278 struct config_item
*opts_item
;
1279 struct uvcg_format
*fmt
;
1280 struct mutex
*su_mutex
= &ch
->item
.ci_group
->cg_subsys
->su_mutex
;
1282 u32
*frm_intrv
, *tmp
;
1284 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
1286 opts_item
= ch
->item
.ci_parent
->ci_parent
->ci_parent
->ci_parent
;
1287 opts
= to_f_uvc_opts(opts_item
);
1288 fmt
= to_uvcg_format(ch
->item
.ci_parent
);
1290 mutex_lock(&opts
->lock
);
1291 if (fmt
->linked
|| opts
->refcnt
) {
1296 ret
= __uvcg_iter_frm_intrv(page
, len
, __uvcg_count_frm_intrv
, &n
);
1300 tmp
= frm_intrv
= kcalloc(n
, sizeof(u32
), GFP_KERNEL
);
1306 ret
= __uvcg_iter_frm_intrv(page
, len
, __uvcg_fill_frm_intrv
, &tmp
);
1312 kfree(ch
->dw_frame_interval
);
1313 ch
->dw_frame_interval
= frm_intrv
;
1314 ch
->frame
.b_frame_interval_type
= n
;
1315 sort(ch
->dw_frame_interval
, n
, sizeof(*ch
->dw_frame_interval
),
1316 uvcg_config_compare_u32
, NULL
);
1320 mutex_unlock(&opts
->lock
);
1321 mutex_unlock(su_mutex
);
1325 UVC_ATTR(uvcg_frame_
, dw_frame_interval
, dwFrameInterval
);
1327 static struct configfs_attribute
*uvcg_frame_attrs
[] = {
1328 &uvcg_frame_attr_b_frame_index
,
1329 &uvcg_frame_attr_bm_capabilities
,
1330 &uvcg_frame_attr_w_width
,
1331 &uvcg_frame_attr_w_height
,
1332 &uvcg_frame_attr_dw_min_bit_rate
,
1333 &uvcg_frame_attr_dw_max_bit_rate
,
1334 &uvcg_frame_attr_dw_max_video_frame_buffer_size
,
1335 &uvcg_frame_attr_dw_default_frame_interval
,
1336 &uvcg_frame_attr_dw_frame_interval
,
1340 static const struct config_item_type uvcg_frame_type
= {
1341 .ct_item_ops
= &uvcg_config_item_ops
,
1342 .ct_attrs
= uvcg_frame_attrs
,
1343 .ct_owner
= THIS_MODULE
,
1346 static struct config_item
*uvcg_frame_make(struct config_group
*group
,
1349 struct uvcg_frame
*h
;
1350 struct uvcg_format
*fmt
;
1351 struct f_uvc_opts
*opts
;
1352 struct config_item
*opts_item
;
1354 h
= kzalloc(sizeof(*h
), GFP_KERNEL
);
1356 return ERR_PTR(-ENOMEM
);
1358 h
->frame
.b_descriptor_type
= USB_DT_CS_INTERFACE
;
1359 h
->frame
.b_frame_index
= 1;
1360 h
->frame
.w_width
= 640;
1361 h
->frame
.w_height
= 360;
1362 h
->frame
.dw_min_bit_rate
= 18432000;
1363 h
->frame
.dw_max_bit_rate
= 55296000;
1364 h
->frame
.dw_max_video_frame_buffer_size
= 460800;
1365 h
->frame
.dw_default_frame_interval
= 666666;
1367 opts_item
= group
->cg_item
.ci_parent
->ci_parent
->ci_parent
;
1368 opts
= to_f_uvc_opts(opts_item
);
1370 mutex_lock(&opts
->lock
);
1371 fmt
= to_uvcg_format(&group
->cg_item
);
1372 if (fmt
->type
== UVCG_UNCOMPRESSED
) {
1373 h
->frame
.b_descriptor_subtype
= UVC_VS_FRAME_UNCOMPRESSED
;
1374 h
->fmt_type
= UVCG_UNCOMPRESSED
;
1375 } else if (fmt
->type
== UVCG_MJPEG
) {
1376 h
->frame
.b_descriptor_subtype
= UVC_VS_FRAME_MJPEG
;
1377 h
->fmt_type
= UVCG_MJPEG
;
1379 mutex_unlock(&opts
->lock
);
1381 return ERR_PTR(-EINVAL
);
1384 mutex_unlock(&opts
->lock
);
1386 config_item_init_type_name(&h
->item
, name
, &uvcg_frame_type
);
1391 static void uvcg_frame_drop(struct config_group
*group
, struct config_item
*item
)
1393 struct uvcg_format
*fmt
;
1394 struct f_uvc_opts
*opts
;
1395 struct config_item
*opts_item
;
1397 opts_item
= group
->cg_item
.ci_parent
->ci_parent
->ci_parent
;
1398 opts
= to_f_uvc_opts(opts_item
);
1400 mutex_lock(&opts
->lock
);
1401 fmt
= to_uvcg_format(&group
->cg_item
);
1403 mutex_unlock(&opts
->lock
);
1405 config_item_put(item
);
1408 static void uvcg_format_set_indices(struct config_group
*fmt
)
1410 struct config_item
*ci
;
1413 list_for_each_entry(ci
, &fmt
->cg_children
, ci_entry
) {
1414 struct uvcg_frame
*frm
;
1416 if (ci
->ci_type
!= &uvcg_frame_type
)
1419 frm
= to_uvcg_frame(ci
);
1420 frm
->frame
.b_frame_index
= i
++;
1424 /* -----------------------------------------------------------------------------
1425 * streaming/uncompressed/<NAME>
1428 struct uvcg_uncompressed
{
1429 struct uvcg_format fmt
;
1430 struct uvc_format_uncompressed desc
;
1433 static struct uvcg_uncompressed
*to_uvcg_uncompressed(struct config_item
*item
)
1435 return container_of(
1436 container_of(to_config_group(item
), struct uvcg_format
, group
),
1437 struct uvcg_uncompressed
, fmt
);
1440 static struct configfs_group_operations uvcg_uncompressed_group_ops
= {
1441 .make_item
= uvcg_frame_make
,
1442 .drop_item
= uvcg_frame_drop
,
1445 static ssize_t
uvcg_uncompressed_guid_format_show(struct config_item
*item
,
1448 struct uvcg_uncompressed
*ch
= to_uvcg_uncompressed(item
);
1449 struct f_uvc_opts
*opts
;
1450 struct config_item
*opts_item
;
1451 struct mutex
*su_mutex
= &ch
->fmt
.group
.cg_subsys
->su_mutex
;
1453 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
1455 opts_item
= ch
->fmt
.group
.cg_item
.ci_parent
->ci_parent
->ci_parent
;
1456 opts
= to_f_uvc_opts(opts_item
);
1458 mutex_lock(&opts
->lock
);
1459 memcpy(page
, ch
->desc
.guidFormat
, sizeof(ch
->desc
.guidFormat
));
1460 mutex_unlock(&opts
->lock
);
1462 mutex_unlock(su_mutex
);
1464 return sizeof(ch
->desc
.guidFormat
);
1467 static ssize_t
uvcg_uncompressed_guid_format_store(struct config_item
*item
,
1468 const char *page
, size_t len
)
1470 struct uvcg_uncompressed
*ch
= to_uvcg_uncompressed(item
);
1471 struct f_uvc_opts
*opts
;
1472 struct config_item
*opts_item
;
1473 struct mutex
*su_mutex
= &ch
->fmt
.group
.cg_subsys
->su_mutex
;
1476 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
1478 opts_item
= ch
->fmt
.group
.cg_item
.ci_parent
->ci_parent
->ci_parent
;
1479 opts
= to_f_uvc_opts(opts_item
);
1481 mutex_lock(&opts
->lock
);
1482 if (ch
->fmt
.linked
|| opts
->refcnt
) {
1487 memcpy(ch
->desc
.guidFormat
, page
,
1488 min(sizeof(ch
->desc
.guidFormat
), len
));
1489 ret
= sizeof(ch
->desc
.guidFormat
);
1492 mutex_unlock(&opts
->lock
);
1493 mutex_unlock(su_mutex
);
1497 UVC_ATTR(uvcg_uncompressed_
, guid_format
, guidFormat
);
1499 #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits) \
1500 static ssize_t uvcg_uncompressed_##cname##_show( \
1501 struct config_item *item, char *page) \
1503 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \
1504 struct f_uvc_opts *opts; \
1505 struct config_item *opts_item; \
1506 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
1509 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1511 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1512 opts = to_f_uvc_opts(opts_item); \
1514 mutex_lock(&opts->lock); \
1515 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1516 mutex_unlock(&opts->lock); \
1518 mutex_unlock(su_mutex); \
1522 UVC_ATTR_RO(uvcg_uncompressed_, cname, aname);
1524 #define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits) \
1525 static ssize_t uvcg_uncompressed_##cname##_show( \
1526 struct config_item *item, char *page) \
1528 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \
1529 struct f_uvc_opts *opts; \
1530 struct config_item *opts_item; \
1531 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
1534 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1536 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1537 opts = to_f_uvc_opts(opts_item); \
1539 mutex_lock(&opts->lock); \
1540 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1541 mutex_unlock(&opts->lock); \
1543 mutex_unlock(su_mutex); \
1548 uvcg_uncompressed_##cname##_store(struct config_item *item, \
1549 const char *page, size_t len) \
1551 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \
1552 struct f_uvc_opts *opts; \
1553 struct config_item *opts_item; \
1554 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
1558 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1560 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1561 opts = to_f_uvc_opts(opts_item); \
1563 mutex_lock(&opts->lock); \
1564 if (u->fmt.linked || opts->refcnt) { \
1569 ret = kstrtou8(page, 0, &num); \
1573 u->desc.aname = num; \
1576 mutex_unlock(&opts->lock); \
1577 mutex_unlock(su_mutex); \
1581 UVC_ATTR(uvcg_uncompressed_, cname, aname);
1583 UVCG_UNCOMPRESSED_ATTR_RO(b_format_index
, bFormatIndex
, 8);
1584 UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel
, bBitsPerPixel
, 8);
1585 UVCG_UNCOMPRESSED_ATTR(b_default_frame_index
, bDefaultFrameIndex
, 8);
1586 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x
, bAspectRatioX
, 8);
1587 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y
, bAspectRatioY
, 8);
1588 UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags
, bmInterfaceFlags
, 8);
1590 #undef UVCG_UNCOMPRESSED_ATTR
1591 #undef UVCG_UNCOMPRESSED_ATTR_RO
1593 static inline ssize_t
1594 uvcg_uncompressed_bma_controls_show(struct config_item
*item
, char *page
)
1596 struct uvcg_uncompressed
*unc
= to_uvcg_uncompressed(item
);
1597 return uvcg_format_bma_controls_show(&unc
->fmt
, page
);
1600 static inline ssize_t
1601 uvcg_uncompressed_bma_controls_store(struct config_item
*item
,
1602 const char *page
, size_t len
)
1604 struct uvcg_uncompressed
*unc
= to_uvcg_uncompressed(item
);
1605 return uvcg_format_bma_controls_store(&unc
->fmt
, page
, len
);
1608 UVC_ATTR(uvcg_uncompressed_
, bma_controls
, bmaControls
);
1610 static struct configfs_attribute
*uvcg_uncompressed_attrs
[] = {
1611 &uvcg_uncompressed_attr_b_format_index
,
1612 &uvcg_uncompressed_attr_guid_format
,
1613 &uvcg_uncompressed_attr_b_bits_per_pixel
,
1614 &uvcg_uncompressed_attr_b_default_frame_index
,
1615 &uvcg_uncompressed_attr_b_aspect_ratio_x
,
1616 &uvcg_uncompressed_attr_b_aspect_ratio_y
,
1617 &uvcg_uncompressed_attr_bm_interface_flags
,
1618 &uvcg_uncompressed_attr_bma_controls
,
1622 static const struct config_item_type uvcg_uncompressed_type
= {
1623 .ct_item_ops
= &uvcg_config_item_ops
,
1624 .ct_group_ops
= &uvcg_uncompressed_group_ops
,
1625 .ct_attrs
= uvcg_uncompressed_attrs
,
1626 .ct_owner
= THIS_MODULE
,
1629 static struct config_group
*uvcg_uncompressed_make(struct config_group
*group
,
1632 static char guid
[] = {
1633 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00,
1634 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
1636 struct uvcg_uncompressed
*h
;
1638 h
= kzalloc(sizeof(*h
), GFP_KERNEL
);
1640 return ERR_PTR(-ENOMEM
);
1642 h
->desc
.bLength
= UVC_DT_FORMAT_UNCOMPRESSED_SIZE
;
1643 h
->desc
.bDescriptorType
= USB_DT_CS_INTERFACE
;
1644 h
->desc
.bDescriptorSubType
= UVC_VS_FORMAT_UNCOMPRESSED
;
1645 memcpy(h
->desc
.guidFormat
, guid
, sizeof(guid
));
1646 h
->desc
.bBitsPerPixel
= 16;
1647 h
->desc
.bDefaultFrameIndex
= 1;
1648 h
->desc
.bAspectRatioX
= 0;
1649 h
->desc
.bAspectRatioY
= 0;
1650 h
->desc
.bmInterfaceFlags
= 0;
1651 h
->desc
.bCopyProtect
= 0;
1653 h
->fmt
.type
= UVCG_UNCOMPRESSED
;
1654 config_group_init_type_name(&h
->fmt
.group
, name
,
1655 &uvcg_uncompressed_type
);
1657 return &h
->fmt
.group
;
1660 static struct configfs_group_operations uvcg_uncompressed_grp_ops
= {
1661 .make_group
= uvcg_uncompressed_make
,
1664 static const struct uvcg_config_group_type uvcg_uncompressed_grp_type
= {
1666 .ct_item_ops
= &uvcg_config_item_ops
,
1667 .ct_group_ops
= &uvcg_uncompressed_grp_ops
,
1668 .ct_owner
= THIS_MODULE
,
1670 .name
= "uncompressed",
1673 /* -----------------------------------------------------------------------------
1674 * streaming/mjpeg/<NAME>
1678 struct uvcg_format fmt
;
1679 struct uvc_format_mjpeg desc
;
1682 static struct uvcg_mjpeg
*to_uvcg_mjpeg(struct config_item
*item
)
1684 return container_of(
1685 container_of(to_config_group(item
), struct uvcg_format
, group
),
1686 struct uvcg_mjpeg
, fmt
);
1689 static struct configfs_group_operations uvcg_mjpeg_group_ops
= {
1690 .make_item
= uvcg_frame_make
,
1691 .drop_item
= uvcg_frame_drop
,
1694 #define UVCG_MJPEG_ATTR_RO(cname, aname, bits) \
1695 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
1697 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \
1698 struct f_uvc_opts *opts; \
1699 struct config_item *opts_item; \
1700 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
1703 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1705 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1706 opts = to_f_uvc_opts(opts_item); \
1708 mutex_lock(&opts->lock); \
1709 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1710 mutex_unlock(&opts->lock); \
1712 mutex_unlock(su_mutex); \
1716 UVC_ATTR_RO(uvcg_mjpeg_, cname, aname)
1718 #define UVCG_MJPEG_ATTR(cname, aname, bits) \
1719 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
1721 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \
1722 struct f_uvc_opts *opts; \
1723 struct config_item *opts_item; \
1724 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
1727 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1729 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1730 opts = to_f_uvc_opts(opts_item); \
1732 mutex_lock(&opts->lock); \
1733 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1734 mutex_unlock(&opts->lock); \
1736 mutex_unlock(su_mutex); \
1741 uvcg_mjpeg_##cname##_store(struct config_item *item, \
1742 const char *page, size_t len) \
1744 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \
1745 struct f_uvc_opts *opts; \
1746 struct config_item *opts_item; \
1747 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
1751 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1753 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1754 opts = to_f_uvc_opts(opts_item); \
1756 mutex_lock(&opts->lock); \
1757 if (u->fmt.linked || opts->refcnt) { \
1762 ret = kstrtou8(page, 0, &num); \
1766 u->desc.aname = num; \
1769 mutex_unlock(&opts->lock); \
1770 mutex_unlock(su_mutex); \
1774 UVC_ATTR(uvcg_mjpeg_, cname, aname)
1776 UVCG_MJPEG_ATTR_RO(b_format_index
, bFormatIndex
, 8);
1777 UVCG_MJPEG_ATTR(b_default_frame_index
, bDefaultFrameIndex
, 8);
1778 UVCG_MJPEG_ATTR_RO(bm_flags
, bmFlags
, 8);
1779 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x
, bAspectRatioX
, 8);
1780 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y
, bAspectRatioY
, 8);
1781 UVCG_MJPEG_ATTR_RO(bm_interface_flags
, bmInterfaceFlags
, 8);
1783 #undef UVCG_MJPEG_ATTR
1784 #undef UVCG_MJPEG_ATTR_RO
1786 static inline ssize_t
1787 uvcg_mjpeg_bma_controls_show(struct config_item
*item
, char *page
)
1789 struct uvcg_mjpeg
*u
= to_uvcg_mjpeg(item
);
1790 return uvcg_format_bma_controls_show(&u
->fmt
, page
);
1793 static inline ssize_t
1794 uvcg_mjpeg_bma_controls_store(struct config_item
*item
,
1795 const char *page
, size_t len
)
1797 struct uvcg_mjpeg
*u
= to_uvcg_mjpeg(item
);
1798 return uvcg_format_bma_controls_store(&u
->fmt
, page
, len
);
1801 UVC_ATTR(uvcg_mjpeg_
, bma_controls
, bmaControls
);
1803 static struct configfs_attribute
*uvcg_mjpeg_attrs
[] = {
1804 &uvcg_mjpeg_attr_b_format_index
,
1805 &uvcg_mjpeg_attr_b_default_frame_index
,
1806 &uvcg_mjpeg_attr_bm_flags
,
1807 &uvcg_mjpeg_attr_b_aspect_ratio_x
,
1808 &uvcg_mjpeg_attr_b_aspect_ratio_y
,
1809 &uvcg_mjpeg_attr_bm_interface_flags
,
1810 &uvcg_mjpeg_attr_bma_controls
,
1814 static const struct config_item_type uvcg_mjpeg_type
= {
1815 .ct_item_ops
= &uvcg_config_item_ops
,
1816 .ct_group_ops
= &uvcg_mjpeg_group_ops
,
1817 .ct_attrs
= uvcg_mjpeg_attrs
,
1818 .ct_owner
= THIS_MODULE
,
1821 static struct config_group
*uvcg_mjpeg_make(struct config_group
*group
,
1824 struct uvcg_mjpeg
*h
;
1826 h
= kzalloc(sizeof(*h
), GFP_KERNEL
);
1828 return ERR_PTR(-ENOMEM
);
1830 h
->desc
.bLength
= UVC_DT_FORMAT_MJPEG_SIZE
;
1831 h
->desc
.bDescriptorType
= USB_DT_CS_INTERFACE
;
1832 h
->desc
.bDescriptorSubType
= UVC_VS_FORMAT_MJPEG
;
1833 h
->desc
.bDefaultFrameIndex
= 1;
1834 h
->desc
.bAspectRatioX
= 0;
1835 h
->desc
.bAspectRatioY
= 0;
1836 h
->desc
.bmInterfaceFlags
= 0;
1837 h
->desc
.bCopyProtect
= 0;
1839 h
->fmt
.type
= UVCG_MJPEG
;
1840 config_group_init_type_name(&h
->fmt
.group
, name
,
1843 return &h
->fmt
.group
;
1846 static struct configfs_group_operations uvcg_mjpeg_grp_ops
= {
1847 .make_group
= uvcg_mjpeg_make
,
1850 static const struct uvcg_config_group_type uvcg_mjpeg_grp_type
= {
1852 .ct_item_ops
= &uvcg_config_item_ops
,
1853 .ct_group_ops
= &uvcg_mjpeg_grp_ops
,
1854 .ct_owner
= THIS_MODULE
,
1859 /* -----------------------------------------------------------------------------
1860 * streaming/color_matching/default
1863 #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, bits) \
1864 static ssize_t uvcg_default_color_matching_##cname##_show( \
1865 struct config_item *item, char *page) \
1867 struct config_group *group = to_config_group(item); \
1868 struct f_uvc_opts *opts; \
1869 struct config_item *opts_item; \
1870 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \
1871 struct uvc_color_matching_descriptor *cd; \
1874 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
1876 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \
1877 opts = to_f_uvc_opts(opts_item); \
1878 cd = &opts->uvc_color_matching; \
1880 mutex_lock(&opts->lock); \
1881 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \
1882 mutex_unlock(&opts->lock); \
1884 mutex_unlock(su_mutex); \
1888 UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname)
1890 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries
, bColorPrimaries
, 8);
1891 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics
,
1892 bTransferCharacteristics
, 8);
1893 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients
, bMatrixCoefficients
, 8);
1895 #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR
1897 static struct configfs_attribute
*uvcg_default_color_matching_attrs
[] = {
1898 &uvcg_default_color_matching_attr_b_color_primaries
,
1899 &uvcg_default_color_matching_attr_b_transfer_characteristics
,
1900 &uvcg_default_color_matching_attr_b_matrix_coefficients
,
1904 static const struct uvcg_config_group_type uvcg_default_color_matching_type
= {
1906 .ct_item_ops
= &uvcg_config_item_ops
,
1907 .ct_attrs
= uvcg_default_color_matching_attrs
,
1908 .ct_owner
= THIS_MODULE
,
1913 /* -----------------------------------------------------------------------------
1914 * streaming/color_matching
1917 static const struct uvcg_config_group_type uvcg_color_matching_grp_type
= {
1919 .ct_item_ops
= &uvcg_config_item_ops
,
1920 .ct_owner
= THIS_MODULE
,
1922 .name
= "color_matching",
1923 .children
= (const struct uvcg_config_group_type
*[]) {
1924 &uvcg_default_color_matching_type
,
1929 /* -----------------------------------------------------------------------------
1930 * streaming/class/{fs|hs|ss}
1933 struct uvcg_streaming_class_group
{
1934 struct config_group group
;
1938 static inline struct uvc_descriptor_header
1939 ***__uvcg_get_stream_class_arr(struct config_item
*i
, struct f_uvc_opts
*o
)
1941 struct uvcg_streaming_class_group
*group
=
1942 container_of(i
, struct uvcg_streaming_class_group
,
1945 if (!strcmp(group
->name
, "fs"))
1946 return &o
->uvc_fs_streaming_cls
;
1948 if (!strcmp(group
->name
, "hs"))
1949 return &o
->uvc_hs_streaming_cls
;
1951 if (!strcmp(group
->name
, "ss"))
1952 return &o
->uvc_ss_streaming_cls
;
1957 enum uvcg_strm_type
{
1964 * Iterate over a hierarchy of streaming descriptors' config items.
1965 * The items are created by the user with configfs.
1967 * It "processes" the header pointed to by @priv1, then for each format
1968 * that follows the header "processes" the format itself and then for
1969 * each frame inside a format "processes" the frame.
1971 * As a "processing" function the @fun is used.
1973 * __uvcg_iter_strm_cls() is used in two context: first, to calculate
1974 * the amount of memory needed for an array of streaming descriptors
1975 * and second, to actually fill the array.
1977 * @h: streaming header pointer
1978 * @priv2: an "inout" parameter (the caller might want to see the changes to it)
1979 * @priv3: an "inout" parameter (the caller might want to see the changes to it)
1980 * @fun: callback function for processing each level of the hierarchy
1982 static int __uvcg_iter_strm_cls(struct uvcg_streaming_header
*h
,
1983 void *priv2
, void *priv3
,
1984 int (*fun
)(void *, void *, void *, int, enum uvcg_strm_type type
))
1986 struct uvcg_format_ptr
*f
;
1987 struct config_group
*grp
;
1988 struct config_item
*item
;
1989 struct uvcg_frame
*frm
;
1996 ret
= fun(h
, priv2
, priv3
, 0, UVCG_HEADER
);
1999 list_for_each_entry(f
, &h
->formats
, entry
) {
2000 ret
= fun(f
->fmt
, priv2
, priv3
, i
++, UVCG_FORMAT
);
2003 grp
= &f
->fmt
->group
;
2004 list_for_each_entry(item
, &grp
->cg_children
, ci_entry
) {
2005 frm
= to_uvcg_frame(item
);
2006 ret
= fun(frm
, priv2
, priv3
, j
++, UVCG_FRAME
);
2016 * Count how many bytes are needed for an array of streaming descriptors.
2018 * @priv1: pointer to a header, format or frame
2019 * @priv2: inout parameter, accumulated size of the array
2020 * @priv3: inout parameter, accumulated number of the array elements
2021 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls
2023 static int __uvcg_cnt_strm(void *priv1
, void *priv2
, void *priv3
, int n
,
2024 enum uvcg_strm_type type
)
2026 size_t *size
= priv2
;
2027 size_t *count
= priv3
;
2031 struct uvcg_streaming_header
*h
= priv1
;
2033 *size
+= sizeof(h
->desc
);
2035 *size
+= h
->num_fmt
* UVCG_STREAMING_CONTROL_SIZE
;
2039 struct uvcg_format
*fmt
= priv1
;
2041 if (fmt
->type
== UVCG_UNCOMPRESSED
) {
2042 struct uvcg_uncompressed
*u
=
2043 container_of(fmt
, struct uvcg_uncompressed
,
2046 *size
+= sizeof(u
->desc
);
2047 } else if (fmt
->type
== UVCG_MJPEG
) {
2048 struct uvcg_mjpeg
*m
=
2049 container_of(fmt
, struct uvcg_mjpeg
, fmt
);
2051 *size
+= sizeof(m
->desc
);
2058 struct uvcg_frame
*frm
= priv1
;
2059 int sz
= sizeof(frm
->dw_frame_interval
);
2061 *size
+= sizeof(frm
->frame
);
2062 *size
+= frm
->frame
.b_frame_interval_type
* sz
;
2073 * Fill an array of streaming descriptors.
2075 * @priv1: pointer to a header, format or frame
2076 * @priv2: inout parameter, pointer into a block of memory
2077 * @priv3: inout parameter, pointer to a 2-dimensional array
2079 static int __uvcg_fill_strm(void *priv1
, void *priv2
, void *priv3
, int n
,
2080 enum uvcg_strm_type type
)
2082 void **dest
= priv2
;
2083 struct uvc_descriptor_header
***array
= priv3
;
2091 struct uvc_input_header_descriptor
*ihdr
= *dest
;
2092 struct uvcg_streaming_header
*h
= priv1
;
2093 struct uvcg_format_ptr
*f
;
2095 memcpy(*dest
, &h
->desc
, sizeof(h
->desc
));
2096 *dest
+= sizeof(h
->desc
);
2097 sz
= UVCG_STREAMING_CONTROL_SIZE
;
2098 list_for_each_entry(f
, &h
->formats
, entry
) {
2099 memcpy(*dest
, f
->fmt
->bmaControls
, sz
);
2102 ihdr
->bLength
= sizeof(h
->desc
) + h
->num_fmt
* sz
;
2103 ihdr
->bNumFormats
= h
->num_fmt
;
2107 struct uvcg_format
*fmt
= priv1
;
2109 if (fmt
->type
== UVCG_UNCOMPRESSED
) {
2110 struct uvcg_uncompressed
*u
=
2111 container_of(fmt
, struct uvcg_uncompressed
,
2114 u
->desc
.bFormatIndex
= n
+ 1;
2115 u
->desc
.bNumFrameDescriptors
= fmt
->num_frames
;
2116 memcpy(*dest
, &u
->desc
, sizeof(u
->desc
));
2117 *dest
+= sizeof(u
->desc
);
2118 } else if (fmt
->type
== UVCG_MJPEG
) {
2119 struct uvcg_mjpeg
*m
=
2120 container_of(fmt
, struct uvcg_mjpeg
, fmt
);
2122 m
->desc
.bFormatIndex
= n
+ 1;
2123 m
->desc
.bNumFrameDescriptors
= fmt
->num_frames
;
2124 memcpy(*dest
, &m
->desc
, sizeof(m
->desc
));
2125 *dest
+= sizeof(m
->desc
);
2132 struct uvcg_frame
*frm
= priv1
;
2133 struct uvc_descriptor_header
*h
= *dest
;
2135 sz
= sizeof(frm
->frame
);
2136 memcpy(*dest
, &frm
->frame
, sz
);
2138 sz
= frm
->frame
.b_frame_interval_type
*
2139 sizeof(*frm
->dw_frame_interval
);
2140 memcpy(*dest
, frm
->dw_frame_interval
, sz
);
2142 if (frm
->fmt_type
== UVCG_UNCOMPRESSED
)
2143 h
->bLength
= UVC_DT_FRAME_UNCOMPRESSED_SIZE(
2144 frm
->frame
.b_frame_interval_type
);
2145 else if (frm
->fmt_type
== UVCG_MJPEG
)
2146 h
->bLength
= UVC_DT_FRAME_MJPEG_SIZE(
2147 frm
->frame
.b_frame_interval_type
);
2155 static int uvcg_streaming_class_allow_link(struct config_item
*src
,
2156 struct config_item
*target
)
2158 struct config_item
*streaming
, *header
;
2159 struct f_uvc_opts
*opts
;
2160 struct mutex
*su_mutex
= &src
->ci_group
->cg_subsys
->su_mutex
;
2161 struct uvc_descriptor_header
***class_array
, **cl_arr
;
2162 struct uvcg_streaming_header
*target_hdr
;
2163 void *data
, *data_save
;
2164 size_t size
= 0, count
= 0;
2167 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
2169 streaming
= src
->ci_parent
->ci_parent
;
2170 header
= config_group_find_item(to_config_group(streaming
), "header");
2171 if (!header
|| target
->ci_parent
!= header
)
2174 opts
= to_f_uvc_opts(streaming
->ci_parent
);
2176 mutex_lock(&opts
->lock
);
2178 class_array
= __uvcg_get_stream_class_arr(src
, opts
);
2179 if (!class_array
|| *class_array
|| opts
->refcnt
) {
2184 target_hdr
= to_uvcg_streaming_header(target
);
2185 ret
= __uvcg_iter_strm_cls(target_hdr
, &size
, &count
, __uvcg_cnt_strm
);
2189 count
+= 2; /* color_matching, NULL */
2190 *class_array
= kcalloc(count
, sizeof(void *), GFP_KERNEL
);
2191 if (!*class_array
) {
2196 data
= data_save
= kzalloc(size
, GFP_KERNEL
);
2198 kfree(*class_array
);
2199 *class_array
= NULL
;
2203 cl_arr
= *class_array
;
2204 ret
= __uvcg_iter_strm_cls(target_hdr
, &data
, &cl_arr
,
2207 kfree(*class_array
);
2208 *class_array
= NULL
;
2210 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
2211 * might have advanced the "data", so use a backup copy
2216 *cl_arr
= (struct uvc_descriptor_header
*)&opts
->uvc_color_matching
;
2218 ++target_hdr
->linked
;
2222 mutex_unlock(&opts
->lock
);
2224 config_item_put(header
);
2225 mutex_unlock(su_mutex
);
2229 static void uvcg_streaming_class_drop_link(struct config_item
*src
,
2230 struct config_item
*target
)
2232 struct config_item
*streaming
, *header
;
2233 struct f_uvc_opts
*opts
;
2234 struct mutex
*su_mutex
= &src
->ci_group
->cg_subsys
->su_mutex
;
2235 struct uvc_descriptor_header
***class_array
;
2236 struct uvcg_streaming_header
*target_hdr
;
2238 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
2240 streaming
= src
->ci_parent
->ci_parent
;
2241 header
= config_group_find_item(to_config_group(streaming
), "header");
2242 if (!header
|| target
->ci_parent
!= header
)
2245 opts
= to_f_uvc_opts(streaming
->ci_parent
);
2247 mutex_lock(&opts
->lock
);
2249 class_array
= __uvcg_get_stream_class_arr(src
, opts
);
2250 if (!class_array
|| !*class_array
)
2256 target_hdr
= to_uvcg_streaming_header(target
);
2257 --target_hdr
->linked
;
2258 kfree(**class_array
);
2259 kfree(*class_array
);
2260 *class_array
= NULL
;
2263 mutex_unlock(&opts
->lock
);
2265 config_item_put(header
);
2266 mutex_unlock(su_mutex
);
2269 static struct configfs_item_operations uvcg_streaming_class_item_ops
= {
2270 .release
= uvcg_config_item_release
,
2271 .allow_link
= uvcg_streaming_class_allow_link
,
2272 .drop_link
= uvcg_streaming_class_drop_link
,
2275 static const struct config_item_type uvcg_streaming_class_type
= {
2276 .ct_item_ops
= &uvcg_streaming_class_item_ops
,
2277 .ct_owner
= THIS_MODULE
,
2280 /* -----------------------------------------------------------------------------
2284 static int uvcg_streaming_class_create_children(struct config_group
*parent
)
2286 static const char * const names
[] = { "fs", "hs", "ss" };
2289 for (i
= 0; i
< ARRAY_SIZE(names
); ++i
) {
2290 struct uvcg_streaming_class_group
*group
;
2292 group
= kzalloc(sizeof(*group
), GFP_KERNEL
);
2296 group
->name
= names
[i
];
2298 config_group_init_type_name(&group
->group
, group
->name
,
2299 &uvcg_streaming_class_type
);
2300 configfs_add_default_group(&group
->group
, parent
);
2306 static const struct uvcg_config_group_type uvcg_streaming_class_grp_type
= {
2308 .ct_item_ops
= &uvcg_config_item_ops
,
2309 .ct_owner
= THIS_MODULE
,
2312 .create_children
= uvcg_streaming_class_create_children
,
2315 /* -----------------------------------------------------------------------------
2319 static ssize_t
uvcg_default_streaming_b_interface_number_show(
2320 struct config_item
*item
, char *page
)
2322 struct config_group
*group
= to_config_group(item
);
2323 struct mutex
*su_mutex
= &group
->cg_subsys
->su_mutex
;
2324 struct config_item
*opts_item
;
2325 struct f_uvc_opts
*opts
;
2328 mutex_lock(su_mutex
); /* for navigating configfs hierarchy */
2330 opts_item
= item
->ci_parent
;
2331 opts
= to_f_uvc_opts(opts_item
);
2333 mutex_lock(&opts
->lock
);
2334 result
+= sprintf(page
, "%u\n", opts
->streaming_interface
);
2335 mutex_unlock(&opts
->lock
);
2337 mutex_unlock(su_mutex
);
2342 UVC_ATTR_RO(uvcg_default_streaming_
, b_interface_number
, bInterfaceNumber
);
2344 static struct configfs_attribute
*uvcg_default_streaming_attrs
[] = {
2345 &uvcg_default_streaming_attr_b_interface_number
,
2349 static const struct uvcg_config_group_type uvcg_streaming_grp_type
= {
2351 .ct_item_ops
= &uvcg_config_item_ops
,
2352 .ct_attrs
= uvcg_default_streaming_attrs
,
2353 .ct_owner
= THIS_MODULE
,
2355 .name
= "streaming",
2356 .children
= (const struct uvcg_config_group_type
*[]) {
2357 &uvcg_streaming_header_grp_type
,
2358 &uvcg_uncompressed_grp_type
,
2359 &uvcg_mjpeg_grp_type
,
2360 &uvcg_color_matching_grp_type
,
2361 &uvcg_streaming_class_grp_type
,
2366 /* -----------------------------------------------------------------------------
2370 static void uvc_func_item_release(struct config_item
*item
)
2372 struct f_uvc_opts
*opts
= to_f_uvc_opts(item
);
2374 uvcg_config_remove_children(to_config_group(item
));
2375 usb_put_function_instance(&opts
->func_inst
);
2378 static struct configfs_item_operations uvc_func_item_ops
= {
2379 .release
= uvc_func_item_release
,
2382 #define UVCG_OPTS_ATTR(cname, aname, limit) \
2383 static ssize_t f_uvc_opts_##cname##_show( \
2384 struct config_item *item, char *page) \
2386 struct f_uvc_opts *opts = to_f_uvc_opts(item); \
2389 mutex_lock(&opts->lock); \
2390 result = sprintf(page, "%u\n", opts->cname); \
2391 mutex_unlock(&opts->lock); \
2397 f_uvc_opts_##cname##_store(struct config_item *item, \
2398 const char *page, size_t len) \
2400 struct f_uvc_opts *opts = to_f_uvc_opts(item); \
2404 mutex_lock(&opts->lock); \
2405 if (opts->refcnt) { \
2410 ret = kstrtouint(page, 0, &num); \
2414 if (num > limit) { \
2418 opts->cname = num; \
2421 mutex_unlock(&opts->lock); \
2425 UVC_ATTR(f_uvc_opts_, cname, cname)
2427 UVCG_OPTS_ATTR(streaming_interval
, streaming_interval
, 16);
2428 UVCG_OPTS_ATTR(streaming_maxpacket
, streaming_maxpacket
, 3072);
2429 UVCG_OPTS_ATTR(streaming_maxburst
, streaming_maxburst
, 15);
2431 #undef UVCG_OPTS_ATTR
2433 static struct configfs_attribute
*uvc_attrs
[] = {
2434 &f_uvc_opts_attr_streaming_interval
,
2435 &f_uvc_opts_attr_streaming_maxpacket
,
2436 &f_uvc_opts_attr_streaming_maxburst
,
2440 static const struct uvcg_config_group_type uvc_func_type
= {
2442 .ct_item_ops
= &uvc_func_item_ops
,
2443 .ct_attrs
= uvc_attrs
,
2444 .ct_owner
= THIS_MODULE
,
2447 .children
= (const struct uvcg_config_group_type
*[]) {
2448 &uvcg_control_grp_type
,
2449 &uvcg_streaming_grp_type
,
2454 int uvcg_attach_configfs(struct f_uvc_opts
*opts
)
2458 config_group_init_type_name(&opts
->func_inst
.group
, uvc_func_type
.name
,
2459 &uvc_func_type
.type
);
2461 ret
= uvcg_config_create_children(&opts
->func_inst
.group
,
2464 config_group_put(&opts
->func_inst
.group
);