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