1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * uvc_configfs.c 4 * 5 * Configfs support for the uvc function. 6 * 7 * Copyright (c) 2014 Samsung Electronics Co., Ltd. 8 * http://www.samsung.com 9 * 10 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> 11 */ 12 13 #include <linux/sort.h> 14 15 #include "u_uvc.h" 16 #include "uvc_configfs.h" 17 18 /* ----------------------------------------------------------------------------- 19 * Global Utility Structures and Macros 20 */ 21 22 #define UVCG_STREAMING_CONTROL_SIZE 1 23 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, \ 31 } 32 33 #define UVC_ATTR_RO(prefix, cname, aname) \ 34 static struct configfs_attribute prefix##attr_##cname = { \ 35 .ca_name = __stringify(aname), \ 36 .ca_mode = S_IRUGO, \ 37 .ca_owner = THIS_MODULE, \ 38 .show = prefix##cname##_show, \ 39 } 40 41 #define le8_to_cpu(x) (x) 42 #define cpu_to_le8(x) (x) 43 44 static int uvcg_config_compare_u32(const void *l, const void *r) 45 { 46 u32 li = *(const u32 *)l; 47 u32 ri = *(const u32 *)r; 48 49 return li < ri ? -1 : li == ri ? 0 : 1; 50 } 51 52 static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item) 53 { 54 return container_of(to_config_group(item), struct f_uvc_opts, 55 func_inst.group); 56 } 57 58 struct uvcg_config_group_type { 59 struct config_item_type type; 60 const char *name; 61 const struct uvcg_config_group_type **children; 62 int (*create_children)(struct config_group *group); 63 }; 64 65 static void uvcg_config_item_release(struct config_item *item) 66 { 67 struct config_group *group = to_config_group(item); 68 69 kfree(group); 70 } 71 72 static struct configfs_item_operations uvcg_config_item_ops = { 73 .release = uvcg_config_item_release, 74 }; 75 76 static int uvcg_config_create_group(struct config_group *parent, 77 const struct uvcg_config_group_type *type); 78 79 static int uvcg_config_create_children(struct config_group *group, 80 const struct uvcg_config_group_type *type) 81 { 82 const struct uvcg_config_group_type **child; 83 int ret; 84 85 if (type->create_children) 86 return type->create_children(group); 87 88 for (child = type->children; child && *child; ++child) { 89 ret = uvcg_config_create_group(group, *child); 90 if (ret < 0) 91 return ret; 92 } 93 94 return 0; 95 } 96 97 static int uvcg_config_create_group(struct config_group *parent, 98 const struct uvcg_config_group_type *type) 99 { 100 struct config_group *group; 101 102 group = kzalloc(sizeof(*group), GFP_KERNEL); 103 if (!group) 104 return -ENOMEM; 105 106 config_group_init_type_name(group, type->name, &type->type); 107 configfs_add_default_group(group, parent); 108 109 return uvcg_config_create_children(group, type); 110 } 111 112 static void uvcg_config_remove_children(struct config_group *group) 113 { 114 struct config_group *child, *n; 115 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); 120 } 121 } 122 123 /* ----------------------------------------------------------------------------- 124 * control/header/<NAME> 125 * control/header 126 */ 127 128 DECLARE_UVC_HEADER_DESCRIPTOR(1); 129 130 struct uvcg_control_header { 131 struct config_item item; 132 struct UVC_HEADER_DESCRIPTOR(1) desc; 133 unsigned linked; 134 }; 135 136 static struct uvcg_control_header *to_uvcg_control_header(struct config_item *item) 137 { 138 return container_of(item, struct uvcg_control_header, item); 139 } 140 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) \ 144 { \ 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;\ 149 int result; \ 150 \ 151 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 152 \ 153 opts_item = ch->item.ci_parent->ci_parent->ci_parent; \ 154 opts = to_f_uvc_opts(opts_item); \ 155 \ 156 mutex_lock(&opts->lock); \ 157 result = sprintf(page, "%u\n", le##bits##_to_cpu(ch->desc.aname));\ 158 mutex_unlock(&opts->lock); \ 159 \ 160 mutex_unlock(su_mutex); \ 161 return result; \ 162 } \ 163 \ 164 static ssize_t \ 165 uvcg_control_header_##cname##_store(struct config_item *item, \ 166 const char *page, size_t len) \ 167 { \ 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;\ 172 int ret; \ 173 u##bits num; \ 174 \ 175 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 176 \ 177 opts_item = ch->item.ci_parent->ci_parent->ci_parent; \ 178 opts = to_f_uvc_opts(opts_item); \ 179 \ 180 mutex_lock(&opts->lock); \ 181 if (ch->linked || opts->refcnt) { \ 182 ret = -EBUSY; \ 183 goto end; \ 184 } \ 185 \ 186 ret = kstrtou##bits(page, 0, &num); \ 187 if (ret) \ 188 goto end; \ 189 \ 190 if (num > limit) { \ 191 ret = -EINVAL; \ 192 goto end; \ 193 } \ 194 ch->desc.aname = cpu_to_le##bits(num); \ 195 ret = len; \ 196 end: \ 197 mutex_unlock(&opts->lock); \ 198 mutex_unlock(su_mutex); \ 199 return ret; \ 200 } \ 201 \ 202 UVC_ATTR(uvcg_control_header_, cname, aname) 203 204 UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, 16, 0xffff); 205 206 UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, 32, 0x7fffffff); 207 208 #undef UVCG_CTRL_HDR_ATTR 209 210 static struct configfs_attribute *uvcg_control_header_attrs[] = { 211 &uvcg_control_header_attr_bcd_uvc, 212 &uvcg_control_header_attr_dw_clock_frequency, 213 NULL, 214 }; 215 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, 220 }; 221 222 static struct config_item *uvcg_control_header_make(struct config_group *group, 223 const char *name) 224 { 225 struct uvcg_control_header *h; 226 227 h = kzalloc(sizeof(*h), GFP_KERNEL); 228 if (!h) 229 return ERR_PTR(-ENOMEM); 230 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); 236 237 config_item_init_type_name(&h->item, name, &uvcg_control_header_type); 238 239 return &h->item; 240 } 241 242 static struct configfs_group_operations uvcg_control_header_grp_ops = { 243 .make_item = uvcg_control_header_make, 244 }; 245 246 static const struct uvcg_config_group_type uvcg_control_header_grp_type = { 247 .type = { 248 .ct_item_ops = &uvcg_config_item_ops, 249 .ct_group_ops = &uvcg_control_header_grp_ops, 250 .ct_owner = THIS_MODULE, 251 }, 252 .name = "header", 253 }; 254 255 /* ----------------------------------------------------------------------------- 256 * control/processing/default 257 */ 258 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) \ 262 { \ 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; \ 268 int result; \ 269 \ 270 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 271 \ 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; \ 275 \ 276 mutex_lock(&opts->lock); \ 277 result = sprintf(page, "%u\n", le##bits##_to_cpu(pd->aname)); \ 278 mutex_unlock(&opts->lock); \ 279 \ 280 mutex_unlock(su_mutex); \ 281 return result; \ 282 } \ 283 \ 284 UVC_ATTR_RO(uvcg_default_processing_, cname, aname) 285 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); 290 291 #undef UVCG_DEFAULT_PROCESSING_ATTR 292 293 static ssize_t uvcg_default_processing_bm_controls_show( 294 struct config_item *item, char *page) 295 { 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; 301 int result, i; 302 char *pg = page; 303 304 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 305 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; 309 310 mutex_lock(&opts->lock); 311 for (result = 0, i = 0; i < pd->bControlSize; ++i) { 312 result += sprintf(pg, "%u\n", pd->bmControls[i]); 313 pg = page + result; 314 } 315 mutex_unlock(&opts->lock); 316 317 mutex_unlock(su_mutex); 318 319 return result; 320 } 321 322 UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls); 323 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, 330 NULL, 331 }; 332 333 static const struct uvcg_config_group_type uvcg_default_processing_type = { 334 .type = { 335 .ct_item_ops = &uvcg_config_item_ops, 336 .ct_attrs = uvcg_default_processing_attrs, 337 .ct_owner = THIS_MODULE, 338 }, 339 .name = "default", 340 }; 341 342 /* ----------------------------------------------------------------------------- 343 * control/processing 344 */ 345 346 static const struct uvcg_config_group_type uvcg_processing_grp_type = { 347 .type = { 348 .ct_item_ops = &uvcg_config_item_ops, 349 .ct_owner = THIS_MODULE, 350 }, 351 .name = "processing", 352 .children = (const struct uvcg_config_group_type*[]) { 353 &uvcg_default_processing_type, 354 NULL, 355 }, 356 }; 357 358 /* ----------------------------------------------------------------------------- 359 * control/terminal/camera/default 360 */ 361 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) \ 365 { \ 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; \ 371 int result; \ 372 \ 373 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 374 \ 375 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> \ 376 ci_parent; \ 377 opts = to_f_uvc_opts(opts_item); \ 378 cd = &opts->uvc_camera_terminal; \ 379 \ 380 mutex_lock(&opts->lock); \ 381 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \ 382 mutex_unlock(&opts->lock); \ 383 \ 384 mutex_unlock(su_mutex); \ 385 \ 386 return result; \ 387 } \ 388 \ 389 UVC_ATTR_RO(uvcg_default_camera_, cname, aname) 390 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, 396 16); 397 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax, 398 16); 399 UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength, 400 16); 401 402 #undef UVCG_DEFAULT_CAMERA_ATTR 403 404 static ssize_t uvcg_default_camera_bm_controls_show( 405 struct config_item *item, char *page) 406 { 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; 412 int result, i; 413 char *pg = page; 414 415 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 416 417 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> 418 ci_parent; 419 opts = to_f_uvc_opts(opts_item); 420 cd = &opts->uvc_camera_terminal; 421 422 mutex_lock(&opts->lock); 423 for (result = 0, i = 0; i < cd->bControlSize; ++i) { 424 result += sprintf(pg, "%u\n", cd->bmControls[i]); 425 pg = page + result; 426 } 427 mutex_unlock(&opts->lock); 428 429 mutex_unlock(su_mutex); 430 return result; 431 } 432 433 UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls); 434 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, 444 NULL, 445 }; 446 447 static const struct uvcg_config_group_type uvcg_default_camera_type = { 448 .type = { 449 .ct_item_ops = &uvcg_config_item_ops, 450 .ct_attrs = uvcg_default_camera_attrs, 451 .ct_owner = THIS_MODULE, 452 }, 453 .name = "default", 454 }; 455 456 /* ----------------------------------------------------------------------------- 457 * control/terminal/camera 458 */ 459 460 static const struct uvcg_config_group_type uvcg_camera_grp_type = { 461 .type = { 462 .ct_item_ops = &uvcg_config_item_ops, 463 .ct_owner = THIS_MODULE, 464 }, 465 .name = "camera", 466 .children = (const struct uvcg_config_group_type*[]) { 467 &uvcg_default_camera_type, 468 NULL, 469 }, 470 }; 471 472 /* ----------------------------------------------------------------------------- 473 * control/terminal/output/default 474 */ 475 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) \ 479 { \ 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; \ 485 int result; \ 486 \ 487 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 488 \ 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; \ 493 \ 494 mutex_lock(&opts->lock); \ 495 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \ 496 mutex_unlock(&opts->lock); \ 497 \ 498 mutex_unlock(su_mutex); \ 499 \ 500 return result; \ 501 } \ 502 \ 503 UVC_ATTR_RO(uvcg_default_output_, cname, aname) 504 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); 510 511 #undef UVCG_DEFAULT_OUTPUT_ATTR 512 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, 519 NULL, 520 }; 521 522 static const struct uvcg_config_group_type uvcg_default_output_type = { 523 .type = { 524 .ct_item_ops = &uvcg_config_item_ops, 525 .ct_attrs = uvcg_default_output_attrs, 526 .ct_owner = THIS_MODULE, 527 }, 528 .name = "default", 529 }; 530 531 /* ----------------------------------------------------------------------------- 532 * control/terminal/output 533 */ 534 535 static const struct uvcg_config_group_type uvcg_output_grp_type = { 536 .type = { 537 .ct_item_ops = &uvcg_config_item_ops, 538 .ct_owner = THIS_MODULE, 539 }, 540 .name = "output", 541 .children = (const struct uvcg_config_group_type*[]) { 542 &uvcg_default_output_type, 543 NULL, 544 }, 545 }; 546 547 /* ----------------------------------------------------------------------------- 548 * control/terminal 549 */ 550 551 static const struct uvcg_config_group_type uvcg_terminal_grp_type = { 552 .type = { 553 .ct_item_ops = &uvcg_config_item_ops, 554 .ct_owner = THIS_MODULE, 555 }, 556 .name = "terminal", 557 .children = (const struct uvcg_config_group_type*[]) { 558 &uvcg_camera_grp_type, 559 &uvcg_output_grp_type, 560 NULL, 561 }, 562 }; 563 564 /* ----------------------------------------------------------------------------- 565 * control/class/{fs|ss} 566 */ 567 568 struct uvcg_control_class_group { 569 struct config_group group; 570 const char *name; 571 }; 572 573 static inline struct uvc_descriptor_header 574 **uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o) 575 { 576 struct uvcg_control_class_group *group = 577 container_of(i, struct uvcg_control_class_group, 578 group.cg_item); 579 580 if (!strcmp(group->name, "fs")) 581 return o->uvc_fs_control_cls; 582 583 if (!strcmp(group->name, "ss")) 584 return o->uvc_ss_control_cls; 585 586 return NULL; 587 } 588 589 static int uvcg_control_class_allow_link(struct config_item *src, 590 struct config_item *target) 591 { 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; 597 int ret = -EINVAL; 598 599 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 600 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) 604 goto out; 605 606 opts = to_f_uvc_opts(control->ci_parent); 607 608 mutex_lock(&opts->lock); 609 610 class_array = uvcg_get_ctl_class_arr(src, opts); 611 if (!class_array) 612 goto unlock; 613 if (opts->refcnt || class_array[0]) { 614 ret = -EBUSY; 615 goto unlock; 616 } 617 618 target_hdr = to_uvcg_control_header(target); 619 ++target_hdr->linked; 620 class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc; 621 ret = 0; 622 623 unlock: 624 mutex_unlock(&opts->lock); 625 out: 626 config_item_put(header); 627 mutex_unlock(su_mutex); 628 return ret; 629 } 630 631 static void uvcg_control_class_drop_link(struct config_item *src, 632 struct config_item *target) 633 { 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; 639 640 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 641 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) 645 goto out; 646 647 opts = to_f_uvc_opts(control->ci_parent); 648 649 mutex_lock(&opts->lock); 650 651 class_array = uvcg_get_ctl_class_arr(src, opts); 652 if (!class_array || opts->refcnt) 653 goto unlock; 654 655 target_hdr = to_uvcg_control_header(target); 656 --target_hdr->linked; 657 class_array[0] = NULL; 658 659 unlock: 660 mutex_unlock(&opts->lock); 661 out: 662 config_item_put(header); 663 mutex_unlock(su_mutex); 664 } 665 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, 670 }; 671 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, 675 }; 676 677 /* ----------------------------------------------------------------------------- 678 * control/class 679 */ 680 681 static int uvcg_control_class_create_children(struct config_group *parent) 682 { 683 static const char * const names[] = { "fs", "ss" }; 684 unsigned int i; 685 686 for (i = 0; i < ARRAY_SIZE(names); ++i) { 687 struct uvcg_control_class_group *group; 688 689 group = kzalloc(sizeof(*group), GFP_KERNEL); 690 if (!group) 691 return -ENOMEM; 692 693 group->name = names[i]; 694 695 config_group_init_type_name(&group->group, group->name, 696 &uvcg_control_class_type); 697 configfs_add_default_group(&group->group, parent); 698 } 699 700 return 0; 701 } 702 703 static const struct uvcg_config_group_type uvcg_control_class_grp_type = { 704 .type = { 705 .ct_item_ops = &uvcg_config_item_ops, 706 .ct_owner = THIS_MODULE, 707 }, 708 .name = "class", 709 .create_children = uvcg_control_class_create_children, 710 }; 711 712 /* ----------------------------------------------------------------------------- 713 * control 714 */ 715 716 static ssize_t uvcg_default_control_b_interface_number_show( 717 struct config_item *item, char *page) 718 { 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; 723 int result = 0; 724 725 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 726 727 opts_item = item->ci_parent; 728 opts = to_f_uvc_opts(opts_item); 729 730 mutex_lock(&opts->lock); 731 result += sprintf(page, "%u\n", opts->control_interface); 732 mutex_unlock(&opts->lock); 733 734 mutex_unlock(su_mutex); 735 736 return result; 737 } 738 739 UVC_ATTR_RO(uvcg_default_control_, b_interface_number, bInterfaceNumber); 740 741 static struct configfs_attribute *uvcg_default_control_attrs[] = { 742 &uvcg_default_control_attr_b_interface_number, 743 NULL, 744 }; 745 746 static const struct uvcg_config_group_type uvcg_control_grp_type = { 747 .type = { 748 .ct_item_ops = &uvcg_config_item_ops, 749 .ct_attrs = uvcg_default_control_attrs, 750 .ct_owner = THIS_MODULE, 751 }, 752 .name = "control", 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, 758 NULL, 759 }, 760 }; 761 762 /* ----------------------------------------------------------------------------- 763 * streaming/uncompressed 764 * streaming/mjpeg 765 */ 766 767 static const char * const uvcg_format_names[] = { 768 "uncompressed", 769 "mjpeg", 770 }; 771 772 enum uvcg_format_type { 773 UVCG_UNCOMPRESSED = 0, 774 UVCG_MJPEG, 775 }; 776 777 struct uvcg_format { 778 struct config_group group; 779 enum uvcg_format_type type; 780 unsigned linked; 781 unsigned num_frames; 782 __u8 bmaControls[UVCG_STREAMING_CONTROL_SIZE]; 783 }; 784 785 static struct uvcg_format *to_uvcg_format(struct config_item *item) 786 { 787 return container_of(to_config_group(item), struct uvcg_format, group); 788 } 789 790 static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page) 791 { 792 struct f_uvc_opts *opts; 793 struct config_item *opts_item; 794 struct mutex *su_mutex = &f->group.cg_subsys->su_mutex; 795 int result, i; 796 char *pg = page; 797 798 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 799 800 opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent; 801 opts = to_f_uvc_opts(opts_item); 802 803 mutex_lock(&opts->lock); 804 result = sprintf(pg, "0x"); 805 pg += result; 806 for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) { 807 result += sprintf(pg, "%x\n", f->bmaControls[i]); 808 pg = page + result; 809 } 810 mutex_unlock(&opts->lock); 811 812 mutex_unlock(su_mutex); 813 return result; 814 } 815 816 static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch, 817 const char *page, size_t len) 818 { 819 struct f_uvc_opts *opts; 820 struct config_item *opts_item; 821 struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex; 822 int ret = -EINVAL; 823 824 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 825 826 opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent; 827 opts = to_f_uvc_opts(opts_item); 828 829 mutex_lock(&opts->lock); 830 if (ch->linked || opts->refcnt) { 831 ret = -EBUSY; 832 goto end; 833 } 834 835 if (len < 4 || *page != '0' || 836 (*(page + 1) != 'x' && *(page + 1) != 'X')) 837 goto end; 838 ret = hex2bin(ch->bmaControls, page + 2, 1); 839 if (ret < 0) 840 goto end; 841 ret = len; 842 end: 843 mutex_unlock(&opts->lock); 844 mutex_unlock(su_mutex); 845 return ret; 846 } 847 848 struct uvcg_format_ptr { 849 struct uvcg_format *fmt; 850 struct list_head entry; 851 }; 852 853 /* ----------------------------------------------------------------------------- 854 * streaming/header/<NAME> 855 * streaming/header 856 */ 857 858 struct uvcg_streaming_header { 859 struct config_item item; 860 struct uvc_input_header_descriptor desc; 861 unsigned linked; 862 struct list_head formats; 863 unsigned num_fmt; 864 }; 865 866 static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item *item) 867 { 868 return container_of(item, struct uvcg_streaming_header, item); 869 } 870 871 static void uvcg_format_set_indices(struct config_group *fmt); 872 873 static int uvcg_streaming_header_allow_link(struct config_item *src, 874 struct config_item *target) 875 { 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; 883 884 src_hdr = to_uvcg_streaming_header(src); 885 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 886 887 opts_item = src->ci_parent->ci_parent->ci_parent; 888 opts = to_f_uvc_opts(opts_item); 889 890 mutex_lock(&opts->lock); 891 892 if (src_hdr->linked) { 893 ret = -EBUSY; 894 goto out; 895 } 896 897 /* 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 902 * format node. 903 */ 904 if (src->ci_parent->ci_parent != target->ci_parent->ci_parent) 905 goto out; 906 907 for (i = 0; i < ARRAY_SIZE(uvcg_format_names); ++i) { 908 if (!strcmp(target->ci_parent->ci_name, uvcg_format_names[i])) 909 break; 910 } 911 912 if (i == ARRAY_SIZE(uvcg_format_names)) 913 goto out; 914 915 target_fmt = container_of(to_config_group(target), struct uvcg_format, 916 group); 917 if (!target_fmt) 918 goto out; 919 920 uvcg_format_set_indices(to_config_group(target)); 921 922 format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL); 923 if (!format_ptr) { 924 ret = -ENOMEM; 925 goto out; 926 } 927 ret = 0; 928 format_ptr->fmt = target_fmt; 929 list_add_tail(&format_ptr->entry, &src_hdr->formats); 930 ++src_hdr->num_fmt; 931 ++target_fmt->linked; 932 933 out: 934 mutex_unlock(&opts->lock); 935 mutex_unlock(su_mutex); 936 return ret; 937 } 938 939 static void uvcg_streaming_header_drop_link(struct config_item *src, 940 struct config_item *target) 941 { 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; 948 949 src_hdr = to_uvcg_streaming_header(src); 950 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 951 952 opts_item = src->ci_parent->ci_parent->ci_parent; 953 opts = to_f_uvc_opts(opts_item); 954 955 mutex_lock(&opts->lock); 956 target_fmt = container_of(to_config_group(target), struct uvcg_format, 957 group); 958 if (!target_fmt) 959 goto out; 960 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); 964 kfree(format_ptr); 965 --src_hdr->num_fmt; 966 break; 967 } 968 969 --target_fmt->linked; 970 971 out: 972 mutex_unlock(&opts->lock); 973 mutex_unlock(su_mutex); 974 } 975 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, 980 }; 981 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) \ 985 { \ 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;\ 990 int result; \ 991 \ 992 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 993 \ 994 opts_item = sh->item.ci_parent->ci_parent->ci_parent; \ 995 opts = to_f_uvc_opts(opts_item); \ 996 \ 997 mutex_lock(&opts->lock); \ 998 result = sprintf(page, "%u\n", le##bits##_to_cpu(sh->desc.aname));\ 999 mutex_unlock(&opts->lock); \ 1000 \ 1001 mutex_unlock(su_mutex); \ 1002 return result; \ 1003 } \ 1004 \ 1005 UVC_ATTR_RO(uvcg_streaming_header_, cname, aname) 1006 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); 1012 1013 #undef UVCG_STREAMING_HEADER_ATTR 1014 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, 1021 NULL, 1022 }; 1023 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, 1028 }; 1029 1030 static struct config_item 1031 *uvcg_streaming_header_make(struct config_group *group, const char *name) 1032 { 1033 struct uvcg_streaming_header *h; 1034 1035 h = kzalloc(sizeof(*h), GFP_KERNEL); 1036 if (!h) 1037 return ERR_PTR(-ENOMEM); 1038 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; 1044 1045 config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type); 1046 1047 return &h->item; 1048 } 1049 1050 static struct configfs_group_operations uvcg_streaming_header_grp_ops = { 1051 .make_item = uvcg_streaming_header_make, 1052 }; 1053 1054 static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = { 1055 .type = { 1056 .ct_item_ops = &uvcg_config_item_ops, 1057 .ct_group_ops = &uvcg_streaming_header_grp_ops, 1058 .ct_owner = THIS_MODULE, 1059 }, 1060 .name = "header", 1061 }; 1062 1063 /* ----------------------------------------------------------------------------- 1064 * streaming/<mode>/<format>/<NAME> 1065 */ 1066 1067 struct uvcg_frame { 1068 struct config_item item; 1069 enum uvcg_format_type fmt_type; 1070 struct { 1071 u8 b_length; 1072 u8 b_descriptor_type; 1073 u8 b_descriptor_subtype; 1074 u8 b_frame_index; 1075 u8 bm_capabilities; 1076 u16 w_width; 1077 u16 w_height; 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; 1085 }; 1086 1087 static struct uvcg_frame *to_uvcg_frame(struct config_item *item) 1088 { 1089 return container_of(item, struct uvcg_frame, item); 1090 } 1091 1092 #define UVCG_FRAME_ATTR(cname, aname, bits) \ 1093 static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\ 1094 { \ 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;\ 1099 int result; \ 1100 \ 1101 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1102 \ 1103 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1104 opts = to_f_uvc_opts(opts_item); \ 1105 \ 1106 mutex_lock(&opts->lock); \ 1107 result = sprintf(page, "%u\n", f->frame.cname); \ 1108 mutex_unlock(&opts->lock); \ 1109 \ 1110 mutex_unlock(su_mutex); \ 1111 return result; \ 1112 } \ 1113 \ 1114 static ssize_t uvcg_frame_##cname##_store(struct config_item *item, \ 1115 const char *page, size_t len)\ 1116 { \ 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; \ 1123 int ret; \ 1124 \ 1125 ret = kstrtou##bits(page, 0, &num); \ 1126 if (ret) \ 1127 return ret; \ 1128 \ 1129 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1130 \ 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); \ 1134 \ 1135 mutex_lock(&opts->lock); \ 1136 if (fmt->linked || opts->refcnt) { \ 1137 ret = -EBUSY; \ 1138 goto end; \ 1139 } \ 1140 \ 1141 f->frame.cname = num; \ 1142 ret = len; \ 1143 end: \ 1144 mutex_unlock(&opts->lock); \ 1145 mutex_unlock(su_mutex); \ 1146 return ret; \ 1147 } \ 1148 \ 1149 UVC_ATTR(uvcg_frame_, cname, aname); 1150 1151 static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item, 1152 char *page) 1153 { 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; 1160 int result; 1161 1162 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1163 1164 fmt_item = f->item.ci_parent; 1165 fmt = to_uvcg_format(fmt_item); 1166 1167 if (!fmt->linked) { 1168 result = -EBUSY; 1169 goto out; 1170 } 1171 1172 opts_item = fmt_item->ci_parent->ci_parent->ci_parent; 1173 opts = to_f_uvc_opts(opts_item); 1174 1175 mutex_lock(&opts->lock); 1176 result = sprintf(page, "%u\n", f->frame.b_frame_index); 1177 mutex_unlock(&opts->lock); 1178 1179 out: 1180 mutex_unlock(su_mutex); 1181 return result; 1182 } 1183 1184 UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex); 1185 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); 1193 1194 #undef UVCG_FRAME_ATTR 1195 1196 static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item, 1197 char *page) 1198 { 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; 1203 int result, i; 1204 char *pg = page; 1205 1206 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1207 1208 opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; 1209 opts = to_f_uvc_opts(opts_item); 1210 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]); 1214 pg = page + result; 1215 } 1216 mutex_unlock(&opts->lock); 1217 1218 mutex_unlock(su_mutex); 1219 return result; 1220 } 1221 1222 static inline int __uvcg_count_frm_intrv(char *buf, void *priv) 1223 { 1224 ++*((int *)priv); 1225 return 0; 1226 } 1227 1228 static inline int __uvcg_fill_frm_intrv(char *buf, void *priv) 1229 { 1230 u32 num, **interv; 1231 int ret; 1232 1233 ret = kstrtou32(buf, 0, &num); 1234 if (ret) 1235 return ret; 1236 1237 interv = priv; 1238 **interv = num; 1239 ++*interv; 1240 1241 return 0; 1242 } 1243 1244 static int __uvcg_iter_frm_intrv(const char *page, size_t len, 1245 int (*fun)(char *, void *), void *priv) 1246 { 1247 /* sign, base 2 representation, newline, terminator */ 1248 char buf[1 + sizeof(u32) * 8 + 1 + 1]; 1249 const char *pg = page; 1250 int i, ret; 1251 1252 if (!fun) 1253 return -EINVAL; 1254 1255 while (pg - page < len) { 1256 i = 0; 1257 while (i < sizeof(buf) && (pg - page < len) && 1258 *pg != '\0' && *pg != '\n') 1259 buf[i++] = *pg++; 1260 if (i == sizeof(buf)) 1261 return -EINVAL; 1262 while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) 1263 ++pg; 1264 buf[i] = '\0'; 1265 ret = fun(buf, priv); 1266 if (ret) 1267 return ret; 1268 } 1269 1270 return 0; 1271 } 1272 1273 static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item, 1274 const char *page, size_t len) 1275 { 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; 1281 int ret = 0, n = 0; 1282 u32 *frm_intrv, *tmp; 1283 1284 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1285 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); 1289 1290 mutex_lock(&opts->lock); 1291 if (fmt->linked || opts->refcnt) { 1292 ret = -EBUSY; 1293 goto end; 1294 } 1295 1296 ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n); 1297 if (ret) 1298 goto end; 1299 1300 tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); 1301 if (!frm_intrv) { 1302 ret = -ENOMEM; 1303 goto end; 1304 } 1305 1306 ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp); 1307 if (ret) { 1308 kfree(frm_intrv); 1309 goto end; 1310 } 1311 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); 1317 ret = len; 1318 1319 end: 1320 mutex_unlock(&opts->lock); 1321 mutex_unlock(su_mutex); 1322 return ret; 1323 } 1324 1325 UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval); 1326 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, 1337 NULL, 1338 }; 1339 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, 1344 }; 1345 1346 static struct config_item *uvcg_frame_make(struct config_group *group, 1347 const char *name) 1348 { 1349 struct uvcg_frame *h; 1350 struct uvcg_format *fmt; 1351 struct f_uvc_opts *opts; 1352 struct config_item *opts_item; 1353 1354 h = kzalloc(sizeof(*h), GFP_KERNEL); 1355 if (!h) 1356 return ERR_PTR(-ENOMEM); 1357 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; 1366 1367 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 1368 opts = to_f_uvc_opts(opts_item); 1369 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; 1378 } else { 1379 mutex_unlock(&opts->lock); 1380 kfree(h); 1381 return ERR_PTR(-EINVAL); 1382 } 1383 ++fmt->num_frames; 1384 mutex_unlock(&opts->lock); 1385 1386 config_item_init_type_name(&h->item, name, &uvcg_frame_type); 1387 1388 return &h->item; 1389 } 1390 1391 static void uvcg_frame_drop(struct config_group *group, struct config_item *item) 1392 { 1393 struct uvcg_format *fmt; 1394 struct f_uvc_opts *opts; 1395 struct config_item *opts_item; 1396 1397 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 1398 opts = to_f_uvc_opts(opts_item); 1399 1400 mutex_lock(&opts->lock); 1401 fmt = to_uvcg_format(&group->cg_item); 1402 --fmt->num_frames; 1403 mutex_unlock(&opts->lock); 1404 1405 config_item_put(item); 1406 } 1407 1408 static void uvcg_format_set_indices(struct config_group *fmt) 1409 { 1410 struct config_item *ci; 1411 unsigned int i = 1; 1412 1413 list_for_each_entry(ci, &fmt->cg_children, ci_entry) { 1414 struct uvcg_frame *frm; 1415 1416 if (ci->ci_type != &uvcg_frame_type) 1417 continue; 1418 1419 frm = to_uvcg_frame(ci); 1420 frm->frame.b_frame_index = i++; 1421 } 1422 } 1423 1424 /* ----------------------------------------------------------------------------- 1425 * streaming/uncompressed/<NAME> 1426 */ 1427 1428 struct uvcg_uncompressed { 1429 struct uvcg_format fmt; 1430 struct uvc_format_uncompressed desc; 1431 }; 1432 1433 static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item) 1434 { 1435 return container_of( 1436 container_of(to_config_group(item), struct uvcg_format, group), 1437 struct uvcg_uncompressed, fmt); 1438 } 1439 1440 static struct configfs_group_operations uvcg_uncompressed_group_ops = { 1441 .make_item = uvcg_frame_make, 1442 .drop_item = uvcg_frame_drop, 1443 }; 1444 1445 static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item, 1446 char *page) 1447 { 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; 1452 1453 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1454 1455 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 1456 opts = to_f_uvc_opts(opts_item); 1457 1458 mutex_lock(&opts->lock); 1459 memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); 1460 mutex_unlock(&opts->lock); 1461 1462 mutex_unlock(su_mutex); 1463 1464 return sizeof(ch->desc.guidFormat); 1465 } 1466 1467 static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, 1468 const char *page, size_t len) 1469 { 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; 1474 int ret; 1475 1476 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1477 1478 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 1479 opts = to_f_uvc_opts(opts_item); 1480 1481 mutex_lock(&opts->lock); 1482 if (ch->fmt.linked || opts->refcnt) { 1483 ret = -EBUSY; 1484 goto end; 1485 } 1486 1487 memcpy(ch->desc.guidFormat, page, 1488 min(sizeof(ch->desc.guidFormat), len)); 1489 ret = sizeof(ch->desc.guidFormat); 1490 1491 end: 1492 mutex_unlock(&opts->lock); 1493 mutex_unlock(su_mutex); 1494 return ret; 1495 } 1496 1497 UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat); 1498 1499 #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits) \ 1500 static ssize_t uvcg_uncompressed_##cname##_show( \ 1501 struct config_item *item, char *page) \ 1502 { \ 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; \ 1507 int result; \ 1508 \ 1509 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1510 \ 1511 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1512 opts = to_f_uvc_opts(opts_item); \ 1513 \ 1514 mutex_lock(&opts->lock); \ 1515 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 1516 mutex_unlock(&opts->lock); \ 1517 \ 1518 mutex_unlock(su_mutex); \ 1519 return result; \ 1520 } \ 1521 \ 1522 UVC_ATTR_RO(uvcg_uncompressed_, cname, aname); 1523 1524 #define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits) \ 1525 static ssize_t uvcg_uncompressed_##cname##_show( \ 1526 struct config_item *item, char *page) \ 1527 { \ 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; \ 1532 int result; \ 1533 \ 1534 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1535 \ 1536 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1537 opts = to_f_uvc_opts(opts_item); \ 1538 \ 1539 mutex_lock(&opts->lock); \ 1540 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 1541 mutex_unlock(&opts->lock); \ 1542 \ 1543 mutex_unlock(su_mutex); \ 1544 return result; \ 1545 } \ 1546 \ 1547 static ssize_t \ 1548 uvcg_uncompressed_##cname##_store(struct config_item *item, \ 1549 const char *page, size_t len) \ 1550 { \ 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; \ 1555 int ret; \ 1556 u8 num; \ 1557 \ 1558 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1559 \ 1560 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1561 opts = to_f_uvc_opts(opts_item); \ 1562 \ 1563 mutex_lock(&opts->lock); \ 1564 if (u->fmt.linked || opts->refcnt) { \ 1565 ret = -EBUSY; \ 1566 goto end; \ 1567 } \ 1568 \ 1569 ret = kstrtou8(page, 0, &num); \ 1570 if (ret) \ 1571 goto end; \ 1572 \ 1573 if (num > 255) { \ 1574 ret = -EINVAL; \ 1575 goto end; \ 1576 } \ 1577 u->desc.aname = num; \ 1578 ret = len; \ 1579 end: \ 1580 mutex_unlock(&opts->lock); \ 1581 mutex_unlock(su_mutex); \ 1582 return ret; \ 1583 } \ 1584 \ 1585 UVC_ATTR(uvcg_uncompressed_, cname, aname); 1586 1587 UVCG_UNCOMPRESSED_ATTR_RO(b_format_index, bFormatIndex, 8); 1588 UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, 8); 1589 UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); 1590 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); 1591 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); 1592 UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); 1593 1594 #undef UVCG_UNCOMPRESSED_ATTR 1595 #undef UVCG_UNCOMPRESSED_ATTR_RO 1596 1597 static inline ssize_t 1598 uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page) 1599 { 1600 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 1601 return uvcg_format_bma_controls_show(&unc->fmt, page); 1602 } 1603 1604 static inline ssize_t 1605 uvcg_uncompressed_bma_controls_store(struct config_item *item, 1606 const char *page, size_t len) 1607 { 1608 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 1609 return uvcg_format_bma_controls_store(&unc->fmt, page, len); 1610 } 1611 1612 UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls); 1613 1614 static struct configfs_attribute *uvcg_uncompressed_attrs[] = { 1615 &uvcg_uncompressed_attr_b_format_index, 1616 &uvcg_uncompressed_attr_guid_format, 1617 &uvcg_uncompressed_attr_b_bits_per_pixel, 1618 &uvcg_uncompressed_attr_b_default_frame_index, 1619 &uvcg_uncompressed_attr_b_aspect_ratio_x, 1620 &uvcg_uncompressed_attr_b_aspect_ratio_y, 1621 &uvcg_uncompressed_attr_bm_interface_flags, 1622 &uvcg_uncompressed_attr_bma_controls, 1623 NULL, 1624 }; 1625 1626 static const struct config_item_type uvcg_uncompressed_type = { 1627 .ct_item_ops = &uvcg_config_item_ops, 1628 .ct_group_ops = &uvcg_uncompressed_group_ops, 1629 .ct_attrs = uvcg_uncompressed_attrs, 1630 .ct_owner = THIS_MODULE, 1631 }; 1632 1633 static struct config_group *uvcg_uncompressed_make(struct config_group *group, 1634 const char *name) 1635 { 1636 static char guid[] = { 1637 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 1638 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 1639 }; 1640 struct uvcg_uncompressed *h; 1641 1642 h = kzalloc(sizeof(*h), GFP_KERNEL); 1643 if (!h) 1644 return ERR_PTR(-ENOMEM); 1645 1646 h->desc.bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE; 1647 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1648 h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; 1649 memcpy(h->desc.guidFormat, guid, sizeof(guid)); 1650 h->desc.bBitsPerPixel = 16; 1651 h->desc.bDefaultFrameIndex = 1; 1652 h->desc.bAspectRatioX = 0; 1653 h->desc.bAspectRatioY = 0; 1654 h->desc.bmInterfaceFlags = 0; 1655 h->desc.bCopyProtect = 0; 1656 1657 h->fmt.type = UVCG_UNCOMPRESSED; 1658 config_group_init_type_name(&h->fmt.group, name, 1659 &uvcg_uncompressed_type); 1660 1661 return &h->fmt.group; 1662 } 1663 1664 static struct configfs_group_operations uvcg_uncompressed_grp_ops = { 1665 .make_group = uvcg_uncompressed_make, 1666 }; 1667 1668 static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = { 1669 .type = { 1670 .ct_item_ops = &uvcg_config_item_ops, 1671 .ct_group_ops = &uvcg_uncompressed_grp_ops, 1672 .ct_owner = THIS_MODULE, 1673 }, 1674 .name = "uncompressed", 1675 }; 1676 1677 /* ----------------------------------------------------------------------------- 1678 * streaming/mjpeg/<NAME> 1679 */ 1680 1681 struct uvcg_mjpeg { 1682 struct uvcg_format fmt; 1683 struct uvc_format_mjpeg desc; 1684 }; 1685 1686 static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item) 1687 { 1688 return container_of( 1689 container_of(to_config_group(item), struct uvcg_format, group), 1690 struct uvcg_mjpeg, fmt); 1691 } 1692 1693 static struct configfs_group_operations uvcg_mjpeg_group_ops = { 1694 .make_item = uvcg_frame_make, 1695 .drop_item = uvcg_frame_drop, 1696 }; 1697 1698 #define UVCG_MJPEG_ATTR_RO(cname, aname, bits) \ 1699 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 1700 { \ 1701 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1702 struct f_uvc_opts *opts; \ 1703 struct config_item *opts_item; \ 1704 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1705 int result; \ 1706 \ 1707 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1708 \ 1709 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1710 opts = to_f_uvc_opts(opts_item); \ 1711 \ 1712 mutex_lock(&opts->lock); \ 1713 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 1714 mutex_unlock(&opts->lock); \ 1715 \ 1716 mutex_unlock(su_mutex); \ 1717 return result; \ 1718 } \ 1719 \ 1720 UVC_ATTR_RO(uvcg_mjpeg_, cname, aname) 1721 1722 #define UVCG_MJPEG_ATTR(cname, aname, bits) \ 1723 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 1724 { \ 1725 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1726 struct f_uvc_opts *opts; \ 1727 struct config_item *opts_item; \ 1728 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1729 int result; \ 1730 \ 1731 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1732 \ 1733 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1734 opts = to_f_uvc_opts(opts_item); \ 1735 \ 1736 mutex_lock(&opts->lock); \ 1737 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 1738 mutex_unlock(&opts->lock); \ 1739 \ 1740 mutex_unlock(su_mutex); \ 1741 return result; \ 1742 } \ 1743 \ 1744 static ssize_t \ 1745 uvcg_mjpeg_##cname##_store(struct config_item *item, \ 1746 const char *page, size_t len) \ 1747 { \ 1748 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1749 struct f_uvc_opts *opts; \ 1750 struct config_item *opts_item; \ 1751 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1752 int ret; \ 1753 u8 num; \ 1754 \ 1755 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1756 \ 1757 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1758 opts = to_f_uvc_opts(opts_item); \ 1759 \ 1760 mutex_lock(&opts->lock); \ 1761 if (u->fmt.linked || opts->refcnt) { \ 1762 ret = -EBUSY; \ 1763 goto end; \ 1764 } \ 1765 \ 1766 ret = kstrtou8(page, 0, &num); \ 1767 if (ret) \ 1768 goto end; \ 1769 \ 1770 if (num > 255) { \ 1771 ret = -EINVAL; \ 1772 goto end; \ 1773 } \ 1774 u->desc.aname = num; \ 1775 ret = len; \ 1776 end: \ 1777 mutex_unlock(&opts->lock); \ 1778 mutex_unlock(su_mutex); \ 1779 return ret; \ 1780 } \ 1781 \ 1782 UVC_ATTR(uvcg_mjpeg_, cname, aname) 1783 1784 UVCG_MJPEG_ATTR_RO(b_format_index, bFormatIndex, 8); 1785 UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); 1786 UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, 8); 1787 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); 1788 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); 1789 UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); 1790 1791 #undef UVCG_MJPEG_ATTR 1792 #undef UVCG_MJPEG_ATTR_RO 1793 1794 static inline ssize_t 1795 uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page) 1796 { 1797 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 1798 return uvcg_format_bma_controls_show(&u->fmt, page); 1799 } 1800 1801 static inline ssize_t 1802 uvcg_mjpeg_bma_controls_store(struct config_item *item, 1803 const char *page, size_t len) 1804 { 1805 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 1806 return uvcg_format_bma_controls_store(&u->fmt, page, len); 1807 } 1808 1809 UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls); 1810 1811 static struct configfs_attribute *uvcg_mjpeg_attrs[] = { 1812 &uvcg_mjpeg_attr_b_format_index, 1813 &uvcg_mjpeg_attr_b_default_frame_index, 1814 &uvcg_mjpeg_attr_bm_flags, 1815 &uvcg_mjpeg_attr_b_aspect_ratio_x, 1816 &uvcg_mjpeg_attr_b_aspect_ratio_y, 1817 &uvcg_mjpeg_attr_bm_interface_flags, 1818 &uvcg_mjpeg_attr_bma_controls, 1819 NULL, 1820 }; 1821 1822 static const struct config_item_type uvcg_mjpeg_type = { 1823 .ct_item_ops = &uvcg_config_item_ops, 1824 .ct_group_ops = &uvcg_mjpeg_group_ops, 1825 .ct_attrs = uvcg_mjpeg_attrs, 1826 .ct_owner = THIS_MODULE, 1827 }; 1828 1829 static struct config_group *uvcg_mjpeg_make(struct config_group *group, 1830 const char *name) 1831 { 1832 struct uvcg_mjpeg *h; 1833 1834 h = kzalloc(sizeof(*h), GFP_KERNEL); 1835 if (!h) 1836 return ERR_PTR(-ENOMEM); 1837 1838 h->desc.bLength = UVC_DT_FORMAT_MJPEG_SIZE; 1839 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1840 h->desc.bDescriptorSubType = UVC_VS_FORMAT_MJPEG; 1841 h->desc.bDefaultFrameIndex = 1; 1842 h->desc.bAspectRatioX = 0; 1843 h->desc.bAspectRatioY = 0; 1844 h->desc.bmInterfaceFlags = 0; 1845 h->desc.bCopyProtect = 0; 1846 1847 h->fmt.type = UVCG_MJPEG; 1848 config_group_init_type_name(&h->fmt.group, name, 1849 &uvcg_mjpeg_type); 1850 1851 return &h->fmt.group; 1852 } 1853 1854 static struct configfs_group_operations uvcg_mjpeg_grp_ops = { 1855 .make_group = uvcg_mjpeg_make, 1856 }; 1857 1858 static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = { 1859 .type = { 1860 .ct_item_ops = &uvcg_config_item_ops, 1861 .ct_group_ops = &uvcg_mjpeg_grp_ops, 1862 .ct_owner = THIS_MODULE, 1863 }, 1864 .name = "mjpeg", 1865 }; 1866 1867 /* ----------------------------------------------------------------------------- 1868 * streaming/color_matching/default 1869 */ 1870 1871 #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, bits) \ 1872 static ssize_t uvcg_default_color_matching_##cname##_show( \ 1873 struct config_item *item, char *page) \ 1874 { \ 1875 struct config_group *group = to_config_group(item); \ 1876 struct f_uvc_opts *opts; \ 1877 struct config_item *opts_item; \ 1878 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 1879 struct uvc_color_matching_descriptor *cd; \ 1880 int result; \ 1881 \ 1882 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1883 \ 1884 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \ 1885 opts = to_f_uvc_opts(opts_item); \ 1886 cd = &opts->uvc_color_matching; \ 1887 \ 1888 mutex_lock(&opts->lock); \ 1889 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \ 1890 mutex_unlock(&opts->lock); \ 1891 \ 1892 mutex_unlock(su_mutex); \ 1893 return result; \ 1894 } \ 1895 \ 1896 UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname) 1897 1898 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 8); 1899 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics, 1900 bTransferCharacteristics, 8); 1901 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 8); 1902 1903 #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR 1904 1905 static struct configfs_attribute *uvcg_default_color_matching_attrs[] = { 1906 &uvcg_default_color_matching_attr_b_color_primaries, 1907 &uvcg_default_color_matching_attr_b_transfer_characteristics, 1908 &uvcg_default_color_matching_attr_b_matrix_coefficients, 1909 NULL, 1910 }; 1911 1912 static const struct uvcg_config_group_type uvcg_default_color_matching_type = { 1913 .type = { 1914 .ct_item_ops = &uvcg_config_item_ops, 1915 .ct_attrs = uvcg_default_color_matching_attrs, 1916 .ct_owner = THIS_MODULE, 1917 }, 1918 .name = "default", 1919 }; 1920 1921 /* ----------------------------------------------------------------------------- 1922 * streaming/color_matching 1923 */ 1924 1925 static const struct uvcg_config_group_type uvcg_color_matching_grp_type = { 1926 .type = { 1927 .ct_item_ops = &uvcg_config_item_ops, 1928 .ct_owner = THIS_MODULE, 1929 }, 1930 .name = "color_matching", 1931 .children = (const struct uvcg_config_group_type*[]) { 1932 &uvcg_default_color_matching_type, 1933 NULL, 1934 }, 1935 }; 1936 1937 /* ----------------------------------------------------------------------------- 1938 * streaming/class/{fs|hs|ss} 1939 */ 1940 1941 struct uvcg_streaming_class_group { 1942 struct config_group group; 1943 const char *name; 1944 }; 1945 1946 static inline struct uvc_descriptor_header 1947 ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o) 1948 { 1949 struct uvcg_streaming_class_group *group = 1950 container_of(i, struct uvcg_streaming_class_group, 1951 group.cg_item); 1952 1953 if (!strcmp(group->name, "fs")) 1954 return &o->uvc_fs_streaming_cls; 1955 1956 if (!strcmp(group->name, "hs")) 1957 return &o->uvc_hs_streaming_cls; 1958 1959 if (!strcmp(group->name, "ss")) 1960 return &o->uvc_ss_streaming_cls; 1961 1962 return NULL; 1963 } 1964 1965 enum uvcg_strm_type { 1966 UVCG_HEADER = 0, 1967 UVCG_FORMAT, 1968 UVCG_FRAME 1969 }; 1970 1971 /* 1972 * Iterate over a hierarchy of streaming descriptors' config items. 1973 * The items are created by the user with configfs. 1974 * 1975 * It "processes" the header pointed to by @priv1, then for each format 1976 * that follows the header "processes" the format itself and then for 1977 * each frame inside a format "processes" the frame. 1978 * 1979 * As a "processing" function the @fun is used. 1980 * 1981 * __uvcg_iter_strm_cls() is used in two context: first, to calculate 1982 * the amount of memory needed for an array of streaming descriptors 1983 * and second, to actually fill the array. 1984 * 1985 * @h: streaming header pointer 1986 * @priv2: an "inout" parameter (the caller might want to see the changes to it) 1987 * @priv3: an "inout" parameter (the caller might want to see the changes to it) 1988 * @fun: callback function for processing each level of the hierarchy 1989 */ 1990 static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h, 1991 void *priv2, void *priv3, 1992 int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type)) 1993 { 1994 struct uvcg_format_ptr *f; 1995 struct config_group *grp; 1996 struct config_item *item; 1997 struct uvcg_frame *frm; 1998 int ret, i, j; 1999 2000 if (!fun) 2001 return -EINVAL; 2002 2003 i = j = 0; 2004 ret = fun(h, priv2, priv3, 0, UVCG_HEADER); 2005 if (ret) 2006 return ret; 2007 list_for_each_entry(f, &h->formats, entry) { 2008 ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT); 2009 if (ret) 2010 return ret; 2011 grp = &f->fmt->group; 2012 list_for_each_entry(item, &grp->cg_children, ci_entry) { 2013 frm = to_uvcg_frame(item); 2014 ret = fun(frm, priv2, priv3, j++, UVCG_FRAME); 2015 if (ret) 2016 return ret; 2017 } 2018 } 2019 2020 return ret; 2021 } 2022 2023 /* 2024 * Count how many bytes are needed for an array of streaming descriptors. 2025 * 2026 * @priv1: pointer to a header, format or frame 2027 * @priv2: inout parameter, accumulated size of the array 2028 * @priv3: inout parameter, accumulated number of the array elements 2029 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls 2030 */ 2031 static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, 2032 enum uvcg_strm_type type) 2033 { 2034 size_t *size = priv2; 2035 size_t *count = priv3; 2036 2037 switch (type) { 2038 case UVCG_HEADER: { 2039 struct uvcg_streaming_header *h = priv1; 2040 2041 *size += sizeof(h->desc); 2042 /* bmaControls */ 2043 *size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE; 2044 } 2045 break; 2046 case UVCG_FORMAT: { 2047 struct uvcg_format *fmt = priv1; 2048 2049 if (fmt->type == UVCG_UNCOMPRESSED) { 2050 struct uvcg_uncompressed *u = 2051 container_of(fmt, struct uvcg_uncompressed, 2052 fmt); 2053 2054 *size += sizeof(u->desc); 2055 } else if (fmt->type == UVCG_MJPEG) { 2056 struct uvcg_mjpeg *m = 2057 container_of(fmt, struct uvcg_mjpeg, fmt); 2058 2059 *size += sizeof(m->desc); 2060 } else { 2061 return -EINVAL; 2062 } 2063 } 2064 break; 2065 case UVCG_FRAME: { 2066 struct uvcg_frame *frm = priv1; 2067 int sz = sizeof(frm->dw_frame_interval); 2068 2069 *size += sizeof(frm->frame); 2070 *size += frm->frame.b_frame_interval_type * sz; 2071 } 2072 break; 2073 } 2074 2075 ++*count; 2076 2077 return 0; 2078 } 2079 2080 /* 2081 * Fill an array of streaming descriptors. 2082 * 2083 * @priv1: pointer to a header, format or frame 2084 * @priv2: inout parameter, pointer into a block of memory 2085 * @priv3: inout parameter, pointer to a 2-dimensional array 2086 */ 2087 static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, 2088 enum uvcg_strm_type type) 2089 { 2090 void **dest = priv2; 2091 struct uvc_descriptor_header ***array = priv3; 2092 size_t sz; 2093 2094 **array = *dest; 2095 ++*array; 2096 2097 switch (type) { 2098 case UVCG_HEADER: { 2099 struct uvc_input_header_descriptor *ihdr = *dest; 2100 struct uvcg_streaming_header *h = priv1; 2101 struct uvcg_format_ptr *f; 2102 2103 memcpy(*dest, &h->desc, sizeof(h->desc)); 2104 *dest += sizeof(h->desc); 2105 sz = UVCG_STREAMING_CONTROL_SIZE; 2106 list_for_each_entry(f, &h->formats, entry) { 2107 memcpy(*dest, f->fmt->bmaControls, sz); 2108 *dest += sz; 2109 } 2110 ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz; 2111 ihdr->bNumFormats = h->num_fmt; 2112 } 2113 break; 2114 case UVCG_FORMAT: { 2115 struct uvcg_format *fmt = priv1; 2116 2117 if (fmt->type == UVCG_UNCOMPRESSED) { 2118 struct uvcg_uncompressed *u = 2119 container_of(fmt, struct uvcg_uncompressed, 2120 fmt); 2121 2122 u->desc.bFormatIndex = n + 1; 2123 u->desc.bNumFrameDescriptors = fmt->num_frames; 2124 memcpy(*dest, &u->desc, sizeof(u->desc)); 2125 *dest += sizeof(u->desc); 2126 } else if (fmt->type == UVCG_MJPEG) { 2127 struct uvcg_mjpeg *m = 2128 container_of(fmt, struct uvcg_mjpeg, fmt); 2129 2130 m->desc.bFormatIndex = n + 1; 2131 m->desc.bNumFrameDescriptors = fmt->num_frames; 2132 memcpy(*dest, &m->desc, sizeof(m->desc)); 2133 *dest += sizeof(m->desc); 2134 } else { 2135 return -EINVAL; 2136 } 2137 } 2138 break; 2139 case UVCG_FRAME: { 2140 struct uvcg_frame *frm = priv1; 2141 struct uvc_descriptor_header *h = *dest; 2142 2143 sz = sizeof(frm->frame); 2144 memcpy(*dest, &frm->frame, sz); 2145 *dest += sz; 2146 sz = frm->frame.b_frame_interval_type * 2147 sizeof(*frm->dw_frame_interval); 2148 memcpy(*dest, frm->dw_frame_interval, sz); 2149 *dest += sz; 2150 if (frm->fmt_type == UVCG_UNCOMPRESSED) 2151 h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE( 2152 frm->frame.b_frame_interval_type); 2153 else if (frm->fmt_type == UVCG_MJPEG) 2154 h->bLength = UVC_DT_FRAME_MJPEG_SIZE( 2155 frm->frame.b_frame_interval_type); 2156 } 2157 break; 2158 } 2159 2160 return 0; 2161 } 2162 2163 static int uvcg_streaming_class_allow_link(struct config_item *src, 2164 struct config_item *target) 2165 { 2166 struct config_item *streaming, *header; 2167 struct f_uvc_opts *opts; 2168 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 2169 struct uvc_descriptor_header ***class_array, **cl_arr; 2170 struct uvcg_streaming_header *target_hdr; 2171 void *data, *data_save; 2172 size_t size = 0, count = 0; 2173 int ret = -EINVAL; 2174 2175 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2176 2177 streaming = src->ci_parent->ci_parent; 2178 header = config_group_find_item(to_config_group(streaming), "header"); 2179 if (!header || target->ci_parent != header) 2180 goto out; 2181 2182 opts = to_f_uvc_opts(streaming->ci_parent); 2183 2184 mutex_lock(&opts->lock); 2185 2186 class_array = __uvcg_get_stream_class_arr(src, opts); 2187 if (!class_array || *class_array || opts->refcnt) { 2188 ret = -EBUSY; 2189 goto unlock; 2190 } 2191 2192 target_hdr = to_uvcg_streaming_header(target); 2193 ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm); 2194 if (ret) 2195 goto unlock; 2196 2197 count += 2; /* color_matching, NULL */ 2198 *class_array = kcalloc(count, sizeof(void *), GFP_KERNEL); 2199 if (!*class_array) { 2200 ret = -ENOMEM; 2201 goto unlock; 2202 } 2203 2204 data = data_save = kzalloc(size, GFP_KERNEL); 2205 if (!data) { 2206 kfree(*class_array); 2207 *class_array = NULL; 2208 ret = -ENOMEM; 2209 goto unlock; 2210 } 2211 cl_arr = *class_array; 2212 ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr, 2213 __uvcg_fill_strm); 2214 if (ret) { 2215 kfree(*class_array); 2216 *class_array = NULL; 2217 /* 2218 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls() 2219 * might have advanced the "data", so use a backup copy 2220 */ 2221 kfree(data_save); 2222 goto unlock; 2223 } 2224 *cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching; 2225 2226 ++target_hdr->linked; 2227 ret = 0; 2228 2229 unlock: 2230 mutex_unlock(&opts->lock); 2231 out: 2232 config_item_put(header); 2233 mutex_unlock(su_mutex); 2234 return ret; 2235 } 2236 2237 static void uvcg_streaming_class_drop_link(struct config_item *src, 2238 struct config_item *target) 2239 { 2240 struct config_item *streaming, *header; 2241 struct f_uvc_opts *opts; 2242 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 2243 struct uvc_descriptor_header ***class_array; 2244 struct uvcg_streaming_header *target_hdr; 2245 2246 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2247 2248 streaming = src->ci_parent->ci_parent; 2249 header = config_group_find_item(to_config_group(streaming), "header"); 2250 if (!header || target->ci_parent != header) 2251 goto out; 2252 2253 opts = to_f_uvc_opts(streaming->ci_parent); 2254 2255 mutex_lock(&opts->lock); 2256 2257 class_array = __uvcg_get_stream_class_arr(src, opts); 2258 if (!class_array || !*class_array) 2259 goto unlock; 2260 2261 if (opts->refcnt) 2262 goto unlock; 2263 2264 target_hdr = to_uvcg_streaming_header(target); 2265 --target_hdr->linked; 2266 kfree(**class_array); 2267 kfree(*class_array); 2268 *class_array = NULL; 2269 2270 unlock: 2271 mutex_unlock(&opts->lock); 2272 out: 2273 config_item_put(header); 2274 mutex_unlock(su_mutex); 2275 } 2276 2277 static struct configfs_item_operations uvcg_streaming_class_item_ops = { 2278 .release = uvcg_config_item_release, 2279 .allow_link = uvcg_streaming_class_allow_link, 2280 .drop_link = uvcg_streaming_class_drop_link, 2281 }; 2282 2283 static const struct config_item_type uvcg_streaming_class_type = { 2284 .ct_item_ops = &uvcg_streaming_class_item_ops, 2285 .ct_owner = THIS_MODULE, 2286 }; 2287 2288 /* ----------------------------------------------------------------------------- 2289 * streaming/class 2290 */ 2291 2292 static int uvcg_streaming_class_create_children(struct config_group *parent) 2293 { 2294 static const char * const names[] = { "fs", "hs", "ss" }; 2295 unsigned int i; 2296 2297 for (i = 0; i < ARRAY_SIZE(names); ++i) { 2298 struct uvcg_streaming_class_group *group; 2299 2300 group = kzalloc(sizeof(*group), GFP_KERNEL); 2301 if (!group) 2302 return -ENOMEM; 2303 2304 group->name = names[i]; 2305 2306 config_group_init_type_name(&group->group, group->name, 2307 &uvcg_streaming_class_type); 2308 configfs_add_default_group(&group->group, parent); 2309 } 2310 2311 return 0; 2312 } 2313 2314 static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = { 2315 .type = { 2316 .ct_item_ops = &uvcg_config_item_ops, 2317 .ct_owner = THIS_MODULE, 2318 }, 2319 .name = "class", 2320 .create_children = uvcg_streaming_class_create_children, 2321 }; 2322 2323 /* ----------------------------------------------------------------------------- 2324 * streaming 2325 */ 2326 2327 static ssize_t uvcg_default_streaming_b_interface_number_show( 2328 struct config_item *item, char *page) 2329 { 2330 struct config_group *group = to_config_group(item); 2331 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 2332 struct config_item *opts_item; 2333 struct f_uvc_opts *opts; 2334 int result = 0; 2335 2336 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2337 2338 opts_item = item->ci_parent; 2339 opts = to_f_uvc_opts(opts_item); 2340 2341 mutex_lock(&opts->lock); 2342 result += sprintf(page, "%u\n", opts->streaming_interface); 2343 mutex_unlock(&opts->lock); 2344 2345 mutex_unlock(su_mutex); 2346 2347 return result; 2348 } 2349 2350 UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber); 2351 2352 static struct configfs_attribute *uvcg_default_streaming_attrs[] = { 2353 &uvcg_default_streaming_attr_b_interface_number, 2354 NULL, 2355 }; 2356 2357 static const struct uvcg_config_group_type uvcg_streaming_grp_type = { 2358 .type = { 2359 .ct_item_ops = &uvcg_config_item_ops, 2360 .ct_attrs = uvcg_default_streaming_attrs, 2361 .ct_owner = THIS_MODULE, 2362 }, 2363 .name = "streaming", 2364 .children = (const struct uvcg_config_group_type*[]) { 2365 &uvcg_streaming_header_grp_type, 2366 &uvcg_uncompressed_grp_type, 2367 &uvcg_mjpeg_grp_type, 2368 &uvcg_color_matching_grp_type, 2369 &uvcg_streaming_class_grp_type, 2370 NULL, 2371 }, 2372 }; 2373 2374 /* ----------------------------------------------------------------------------- 2375 * UVC function 2376 */ 2377 2378 static void uvc_func_item_release(struct config_item *item) 2379 { 2380 struct f_uvc_opts *opts = to_f_uvc_opts(item); 2381 2382 uvcg_config_remove_children(to_config_group(item)); 2383 usb_put_function_instance(&opts->func_inst); 2384 } 2385 2386 static struct configfs_item_operations uvc_func_item_ops = { 2387 .release = uvc_func_item_release, 2388 }; 2389 2390 #define UVCG_OPTS_ATTR(cname, aname, limit) \ 2391 static ssize_t f_uvc_opts_##cname##_show( \ 2392 struct config_item *item, char *page) \ 2393 { \ 2394 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 2395 int result; \ 2396 \ 2397 mutex_lock(&opts->lock); \ 2398 result = sprintf(page, "%u\n", opts->cname); \ 2399 mutex_unlock(&opts->lock); \ 2400 \ 2401 return result; \ 2402 } \ 2403 \ 2404 static ssize_t \ 2405 f_uvc_opts_##cname##_store(struct config_item *item, \ 2406 const char *page, size_t len) \ 2407 { \ 2408 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 2409 unsigned int num; \ 2410 int ret; \ 2411 \ 2412 mutex_lock(&opts->lock); \ 2413 if (opts->refcnt) { \ 2414 ret = -EBUSY; \ 2415 goto end; \ 2416 } \ 2417 \ 2418 ret = kstrtouint(page, 0, &num); \ 2419 if (ret) \ 2420 goto end; \ 2421 \ 2422 if (num > limit) { \ 2423 ret = -EINVAL; \ 2424 goto end; \ 2425 } \ 2426 opts->cname = num; \ 2427 ret = len; \ 2428 end: \ 2429 mutex_unlock(&opts->lock); \ 2430 return ret; \ 2431 } \ 2432 \ 2433 UVC_ATTR(f_uvc_opts_, cname, cname) 2434 2435 UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16); 2436 UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072); 2437 UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15); 2438 2439 #undef UVCG_OPTS_ATTR 2440 2441 static struct configfs_attribute *uvc_attrs[] = { 2442 &f_uvc_opts_attr_streaming_interval, 2443 &f_uvc_opts_attr_streaming_maxpacket, 2444 &f_uvc_opts_attr_streaming_maxburst, 2445 NULL, 2446 }; 2447 2448 static const struct uvcg_config_group_type uvc_func_type = { 2449 .type = { 2450 .ct_item_ops = &uvc_func_item_ops, 2451 .ct_attrs = uvc_attrs, 2452 .ct_owner = THIS_MODULE, 2453 }, 2454 .name = "", 2455 .children = (const struct uvcg_config_group_type*[]) { 2456 &uvcg_control_grp_type, 2457 &uvcg_streaming_grp_type, 2458 NULL, 2459 }, 2460 }; 2461 2462 int uvcg_attach_configfs(struct f_uvc_opts *opts) 2463 { 2464 int ret; 2465 2466 config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name, 2467 &uvc_func_type.type); 2468 2469 ret = uvcg_config_create_children(&opts->func_inst.group, 2470 &uvc_func_type); 2471 if (ret < 0) 2472 config_group_put(&opts->func_inst.group); 2473 2474 return ret; 2475 } 2476